13c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*-------------------------------------------------------------------------
23c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * drawElements Quality Program OpenGL ES 3.0 Module
33c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * -------------------------------------------------
43c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
53c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Copyright 2014 The Android Open Source Project
63c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
73c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Licensed under the Apache License, Version 2.0 (the "License");
83c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * you may not use this file except in compliance with the License.
93c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * You may obtain a copy of the License at
103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *      http://www.apache.org/licenses/LICENSE-2.0
123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Unless required by applicable law or agreed to in writing, software
143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * distributed under the License is distributed on an "AS IS" BASIS,
153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * See the License for the specific language governing permissions and
173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * limitations under the License.
183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*!
203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \file
213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief ASTC decompression tests
223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \todo Parts of the block-generation code are same as in decompression
243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *		 code in tcuCompressedTexture.cpp ; could put them to some shared
253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *		 ASTC utility file.
263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \todo Tests for void extents with nontrivial extent coordinates.
283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \todo Better checking of the error color. Currently legitimate error
303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *		 pixels are just ignored in image comparison; however, spec says
313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *		 that error color is either magenta or all-NaNs. Can NaNs cause
323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *		 troubles, or can we assume that NaNs are well-supported in shader
333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *		 if the implementation chooses NaNs as error color?
343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "es3fASTCDecompressionCases.hpp"
373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluTexture.hpp"
383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluPixelTransfer.hpp"
393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluStrUtil.hpp"
403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluTextureUtil.hpp"
413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glsTextureTestUtil.hpp"
423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuCompressedTexture.hpp"
433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuTestLog.hpp"
443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuTextureUtil.hpp"
453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuSurface.hpp"
463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuVectorUtil.hpp"
473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuImageCompare.hpp"
483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deStringUtil.hpp"
493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deRandom.hpp"
503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deFloat16.h"
513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deString.h"
523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deMemory.h"
533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glwFunctions.hpp"
553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glwEnums.hpp"
563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <vector>
583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <string>
593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <algorithm>
603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
613c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::TestLog;
623c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::CompressedTexture;
63becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärviusing tcu::CompressedTexFormat;
643c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::IVec2;
653c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::IVec3;
663c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::IVec4;
673c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::Vec2;
683c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::Vec4;
693c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::Sampler;
703c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::Surface;
71efb83e1354edd463650ad0404b18e9a7efc307e4Pyry Haulosusing tcu::astc::BlockTestType;
723c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::vector;
733c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::string;
743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
753c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace deqp
763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
783c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing gls::TextureTestUtil::TextureRenderer;
793c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing gls::TextureTestUtil::RandomViewport;
803c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing gls::TextureTestUtil::ReferenceParams;
813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
823c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace gles3
833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
843c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace Functional
853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
873c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace ASTCDecompressionCaseInternal
883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Get a string describing the data of an ASTC block. Currently contains just hex and bin dumps of the block.
913c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic string astcBlockDataStr (const deUint8* data)
923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	string result;
943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result += "  Hexadecimal (big endian: upper left hex digit is block bits 127 to 124):";
953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		static const char* const hexDigits = "0123456789ABCDEF";
983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
99efb83e1354edd463650ad0404b18e9a7efc307e4Pyry Haulos		for (int i = tcu::astc::BLOCK_SIZE_BYTES-1; i >= 0; i--)
1003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
1013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if ((i+1) % 2 == 0)
1023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				result += "\n    ";
1033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
1043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				result += "  ";
1053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			result += hexDigits[(data[i] & 0xf0) >> 4];
1073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			result += " ";
1083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			result += hexDigits[(data[i] & 0x0f) >> 0];
1093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
1103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result += "\n\n  Binary (big endian: upper left bit is block bit 127):";
1133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
114efb83e1354edd463650ad0404b18e9a7efc307e4Pyry Haulos	for (int i = tcu::astc::BLOCK_SIZE_BYTES-1; i >= 0; i--)
1153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if ((i+1) % 2 == 0)
1173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			result += "\n    ";
1183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
1193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			result += "  ";
1203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int j = 8-1; j >= 0; j--)
1223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
1233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (j == 3)
1243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				result += " ";
1253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			result += (data[i] >> j) & 1 ? "1" : "0";
1273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
1283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result += "\n";
1313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result;
1333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Compare reference and result block images, reporting also the position of the first non-matching block.
1363c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic bool compareBlockImages (const Surface&		reference,
1373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								const Surface&		result,
1383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								const tcu::RGBA&	thresholdRGBA,
1393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								const IVec2&		blockSize,
1403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								int					numNonDummyBlocks,
1413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								IVec2&				firstFailedBlockCoordDst,
1423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								Surface&			errorMaskDst,
1433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								IVec4&				maxDiffDst)
1443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TCU_CHECK_INTERNAL(reference.getWidth() == result.getWidth() && reference.getHeight() == result.getHeight());
1463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int		width		= result.getWidth();
1483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int		height		= result.getHeight();
1493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const IVec4		threshold	= thresholdRGBA.toIVec();
1503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int		numXBlocks	= width / blockSize.x();
1513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(width % blockSize.x() == 0 && height % blockSize.y() == 0);
1533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	errorMaskDst.setSize(width, height);
1553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	firstFailedBlockCoordDst	= IVec2(-1, -1);
1573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	maxDiffDst					= IVec4(0);
1583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int y = 0; y < height; y++)
1603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int x = 0; x < width; x++)
1613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const IVec2 blockCoord = IVec2(x, y) / blockSize;
1633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (blockCoord.y()*numXBlocks + blockCoord.x() < numNonDummyBlocks)
1653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
1663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const IVec4 refPix = reference.getPixel(x, y).toIVec();
1673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (refPix == IVec4(255, 0, 255, 255))
1693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
1703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				// ASTC error color - allow anything in result.
1713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				errorMaskDst.setPixel(x, y, tcu::RGBA(255, 0, 255, 255));
1723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				continue;
1733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
1743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const IVec4		resPix		= result.getPixel(x, y).toIVec();
1763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const IVec4		diff		= tcu::abs(refPix - resPix);
1773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const bool		isOk		= tcu::boolAll(tcu::lessThanEqual(diff, threshold));
1783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			maxDiffDst = tcu::max(maxDiffDst, diff);
1803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
181c215aaa83047ebbaabafef7acd71275a256da6abDejan Mircevski			errorMaskDst.setPixel(x, y, isOk ? tcu::RGBA::green() : tcu::RGBA::red());
1823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (!isOk && firstFailedBlockCoordDst.x() == -1)
1843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				firstFailedBlockCoordDst = blockCoord;
1853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
1863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return boolAll(lessThanEqual(maxDiffDst, threshold));
1893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1913c827367444ee418f129b2c238299f49d3264554Jarkko Poyryenum ASTCSupportLevel
1923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// \note Ordered from smallest subset to full, for convenient comparison.
1943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ASTCSUPPORTLEVEL_NONE = 0,
1953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ASTCSUPPORTLEVEL_LDR,
1963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ASTCSUPPORTLEVEL_HDR,
1973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ASTCSUPPORTLEVEL_FULL
1983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
1993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2005ed2b23bea6e56762a7aef8c8a086ec724517f26Daniel Andrade Groppestatic inline ASTCSupportLevel getASTCSupportLevel (const glu::ContextInfo& contextInfo, const glu::RenderContext& renderCtx)
2013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2025ed2b23bea6e56762a7aef8c8a086ec724517f26Daniel Andrade Groppe	const bool isES32 = glu::contextSupports(renderCtx.getType(), glu::ApiType::es(3, 2));
2035ed2b23bea6e56762a7aef8c8a086ec724517f26Daniel Andrade Groppe
2043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const vector<string>& extensions = contextInfo.getExtensions();
2053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ASTCSupportLevel maxLevel = ASTCSUPPORTLEVEL_NONE;
2073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int extNdx = 0; extNdx < (int)extensions.size(); extNdx++)
2093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const string& ext = extensions[extNdx];
2115ed2b23bea6e56762a7aef8c8a086ec724517f26Daniel Andrade Groppe		if (isES32)
2125ed2b23bea6e56762a7aef8c8a086ec724517f26Daniel Andrade Groppe		{
2135ed2b23bea6e56762a7aef8c8a086ec724517f26Daniel Andrade Groppe			maxLevel = 	de::max(maxLevel, ext == "GL_KHR_texture_compression_astc_hdr"	? ASTCSUPPORTLEVEL_HDR
2145ed2b23bea6e56762a7aef8c8a086ec724517f26Daniel Andrade Groppe										: ext == "GL_OES_texture_compression_astc"		? ASTCSUPPORTLEVEL_FULL
2155ed2b23bea6e56762a7aef8c8a086ec724517f26Daniel Andrade Groppe										: ASTCSUPPORTLEVEL_LDR);
2165ed2b23bea6e56762a7aef8c8a086ec724517f26Daniel Andrade Groppe		}
2175ed2b23bea6e56762a7aef8c8a086ec724517f26Daniel Andrade Groppe		else
2185ed2b23bea6e56762a7aef8c8a086ec724517f26Daniel Andrade Groppe		{
2195ed2b23bea6e56762a7aef8c8a086ec724517f26Daniel Andrade Groppe			maxLevel = 	de::max(maxLevel, ext == "GL_KHR_texture_compression_astc_ldr"	? ASTCSUPPORTLEVEL_LDR
2205ed2b23bea6e56762a7aef8c8a086ec724517f26Daniel Andrade Groppe										: ext == "GL_KHR_texture_compression_astc_hdr"	? ASTCSUPPORTLEVEL_HDR
2215ed2b23bea6e56762a7aef8c8a086ec724517f26Daniel Andrade Groppe										: ext == "GL_OES_texture_compression_astc"		? ASTCSUPPORTLEVEL_FULL
2225ed2b23bea6e56762a7aef8c8a086ec724517f26Daniel Andrade Groppe										: ASTCSUPPORTLEVEL_NONE);
2235ed2b23bea6e56762a7aef8c8a086ec724517f26Daniel Andrade Groppe		}
2243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return maxLevel;
2273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Class handling the common rendering stuff of ASTC cases.
2303c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass ASTCRenderer2D
2313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2323c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
233becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi								ASTCRenderer2D		(Context&				context,
234becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi													 CompressedTexFormat	format,
235becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi													 deUint32				randomSeed);
2363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
237becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi								~ASTCRenderer2D		(void);
2383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
239becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	void						initialize			(int minRenderWidth, int minRenderHeight, const Vec4& colorScale, const Vec4& colorBias);
240becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	void						clear				(void);
2413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
242becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	void						render				(Surface&					referenceDst,
243becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi													 Surface&					resultDst,
244becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi													 const glu::Texture2D&		texture,
245becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi													 const tcu::TextureFormat&	uncompressedFormat);
2463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
247becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	CompressedTexFormat			getFormat			(void) const { return m_format; }
248becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	IVec2						getBlockSize		(void) const { return m_blockSize; }
249becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	ASTCSupportLevel			getASTCSupport		(void) const { DE_ASSERT(m_initialized); return m_astcSupport;	}
2503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2513c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
252becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	Context&					m_context;
253becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	TextureRenderer				m_renderer;
2543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
255becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	const CompressedTexFormat	m_format;
256becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	const IVec2					m_blockSize;
257becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	ASTCSupportLevel			m_astcSupport;
258becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	Vec4						m_colorScale;
259becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	Vec4						m_colorBias;
2603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
261becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	de::Random					m_rnd;
2623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
263becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	bool						m_initialized;
2643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
2653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // ASTCDecompressionCaseInternal
2673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2683c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing namespace ASTCDecompressionCaseInternal;
2693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
270becd5d53015521acf7536ba754de326d8b1da2f3Mika IsojärviASTCRenderer2D::ASTCRenderer2D (Context&			context,
271becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi								CompressedTexFormat	format,
272becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi								deUint32			randomSeed)
2733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_context			(context)
274469002caa1ccd58f59f53a1bf3dbac4cf6a5d817Jarkko Pöyry	, m_renderer		(context.getRenderContext(), context.getTestContext().getLog(), glu::GLSL_VERSION_300_ES, glu::PRECISION_HIGHP)
2753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_format			(format)
276becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	, m_blockSize		(tcu::getBlockPixelSize(format).xy())
2773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_astcSupport		(ASTCSUPPORTLEVEL_NONE)
2783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_colorScale		(-1.0f)
2793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_colorBias		(-1.0f)
2803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_rnd				(randomSeed)
2813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_initialized		(false)
2823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
283becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	DE_ASSERT(tcu::getBlockPixelSize(format).z() == 1);
2843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2863c827367444ee418f129b2c238299f49d3264554Jarkko PoyryASTCRenderer2D::~ASTCRenderer2D (void)
2873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	clear();
2893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2913c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ASTCRenderer2D::initialize (int minRenderWidth, int minRenderHeight, const Vec4& colorScale, const Vec4& colorBias)
2923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(!m_initialized);
2943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::RenderTarget&	renderTarget	= m_context.getRenderTarget();
2963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestLog&					log				= m_context.getTestContext().getLog();
2973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2985ed2b23bea6e56762a7aef8c8a086ec724517f26Daniel Andrade Groppe	m_astcSupport	= getASTCSupportLevel(m_context.getContextInfo(), m_context.getRenderContext());
2993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_colorScale	= colorScale;
3003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_colorBias		= colorBias;
3013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (m_astcSupport)
3033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case ASTCSUPPORTLEVEL_NONE:		log << TestLog::Message << "No ASTC support detected" << TestLog::EndMessage;		throw tcu::NotSupportedError("ASTC not supported");
3053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case ASTCSUPPORTLEVEL_LDR:		log << TestLog::Message << "LDR ASTC support detected" << TestLog::EndMessage;		break;
3063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case ASTCSUPPORTLEVEL_HDR:		log << TestLog::Message << "HDR ASTC support detected" << TestLog::EndMessage;		break;
3073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case ASTCSUPPORTLEVEL_FULL:		log << TestLog::Message << "Full ASTC support detected" << TestLog::EndMessage;		break;
3083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
3093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(false);
3103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (renderTarget.getWidth() < minRenderWidth || renderTarget.getHeight() < minRenderHeight)
3133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw tcu::NotSupportedError("Render target must be at least " + de::toString(minRenderWidth) + "x" + de::toString(minRenderHeight));
3143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::Message << "Using color scale and bias: result = raw * " << colorScale << " + " << colorBias << TestLog::EndMessage;
3163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_initialized = true;
3183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3203c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ASTCRenderer2D::clear (void)
3213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_renderer.clear();
3233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3253c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ASTCRenderer2D::render (Surface& referenceDst, Surface& resultDst, const glu::Texture2D& texture, const tcu::TextureFormat& uncompressedFormat)
3263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(m_initialized);
3283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions&			gl						= m_context.getRenderContext().getFunctions();
3303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glu::RenderContext&		renderCtx				= m_context.getRenderContext();
3313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int						textureWidth			= texture.getRefTexture().getWidth();
3323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int						textureHeight			= texture.getRefTexture().getHeight();
3333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const RandomViewport			viewport				(renderCtx.getRenderTarget(), textureWidth, textureHeight, m_rnd.getUint32());
3343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ReferenceParams					renderParams			(gls::TextureTestUtil::TEXTURETYPE_2D);
3353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<float>					texCoord;
3363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gls::TextureTestUtil::computeQuadTexCoord2D(texCoord, Vec2(0.0f, 0.0f), Vec2(1.0f, 1.0f));
3373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	renderParams.samplerType	= gls::TextureTestUtil::getSamplerType(uncompressedFormat);
3393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	renderParams.sampler		= Sampler(Sampler::CLAMP_TO_EDGE, Sampler::CLAMP_TO_EDGE, Sampler::CLAMP_TO_EDGE, Sampler::NEAREST, Sampler::NEAREST);
3403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	renderParams.colorScale		= m_colorScale;
3413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	renderParams.colorBias		= m_colorBias;
3423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Setup base viewport.
3443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height);
3453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Bind to unit 0.
3473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.activeTexture(GL_TEXTURE0);
3483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.bindTexture(GL_TEXTURE_2D, texture.getGLTexture());
3493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Setup nearest neighbor filtering and clamp-to-edge.
3513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,		GL_CLAMP_TO_EDGE);
3523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,		GL_CLAMP_TO_EDGE);
3533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,	GL_NEAREST);
3543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,	GL_NEAREST);
3553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_EXPECT_NO_ERROR(gl.getError(), "Set texturing state");
3573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Issue GL draws.
3593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_renderer.renderQuad(0, &texCoord[0], renderParams);
3603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.flush();
3613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Compute reference.
3633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	sampleTexture(gls::TextureTestUtil::SurfaceAccess(referenceDst, renderCtx.getRenderTarget().getPixelFormat()), texture.getRefTexture(), &texCoord[0], renderParams);
3643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Read GL-rendered image.
3663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::readPixels(renderCtx, viewport.x, viewport.y, resultDst.getAccess());
3673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
369efb83e1354edd463650ad0404b18e9a7efc307e4Pyry HaulosASTCBlockCase2D::ASTCBlockCase2D (Context&				context,
370efb83e1354edd463650ad0404b18e9a7efc307e4Pyry Haulos								  const char*			name,
371efb83e1354edd463650ad0404b18e9a7efc307e4Pyry Haulos								  const char*			description,
372efb83e1354edd463650ad0404b18e9a7efc307e4Pyry Haulos								  BlockTestType			testType,
373efb83e1354edd463650ad0404b18e9a7efc307e4Pyry Haulos								  CompressedTexFormat	format)
3743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCase				(context, name, description)
3753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_testType			(testType)
3763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_format				(format)
3773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_numBlocksTested		(0)
3783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_currentIteration	(0)
3793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_renderer			(new ASTCRenderer2D(context, format, deStringHash(getName())))
3803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
381efb83e1354edd463650ad0404b18e9a7efc307e4Pyry Haulos	DE_ASSERT(!(tcu::isAstcSRGBFormat(m_format) && tcu::astc::isBlockTestTypeHDROnly(m_testType))); // \note There is no HDR sRGB mode, so these would be redundant.
3823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3843c827367444ee418f129b2c238299f49d3264554Jarkko PoyryASTCBlockCase2D::~ASTCBlockCase2D (void)
3853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ASTCBlockCase2D::deinit();
3873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3893c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ASTCBlockCase2D::init (void)
3903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
391efb83e1354edd463650ad0404b18e9a7efc307e4Pyry Haulos	m_renderer->initialize(64, 64, tcu::astc::getBlockTestTypeColorScale(m_testType), tcu::astc::getBlockTestTypeColorBias(m_testType));
3923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	generateBlockCaseTestData(m_blockData, m_format, m_testType);
3943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(!m_blockData.empty());
395efb83e1354edd463650ad0404b18e9a7efc307e4Pyry Haulos	DE_ASSERT(m_blockData.size() % tcu::astc::BLOCK_SIZE_BYTES == 0);
3963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
397efb83e1354edd463650ad0404b18e9a7efc307e4Pyry Haulos	m_testCtx.getLog() << TestLog::Message << "Total " << m_blockData.size() / tcu::astc::BLOCK_SIZE_BYTES << " blocks to test" << TestLog::EndMessage
3983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					   << TestLog::Message << "Note: Legitimate ASTC error pixels will be ignored when comparing to reference" << TestLog::EndMessage;
3993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4013c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ASTCBlockCase2D::deinit (void)
4023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_renderer->clear();
4043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_blockData.clear();
4053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4073c827367444ee418f129b2c238299f49d3264554Jarkko PoyryASTCBlockCase2D::IterateResult ASTCBlockCase2D::iterate (void)
4083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestLog&						log						= m_testCtx.getLog();
4103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
411efb83e1354edd463650ad0404b18e9a7efc307e4Pyry Haulos	if (m_renderer->getASTCSupport() == ASTCSUPPORTLEVEL_LDR && tcu::astc::isBlockTestTypeHDROnly(m_testType))
4123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "Passing the case immediately, since only LDR support was detected and test only contains HDR blocks" << TestLog::EndMessage;
4143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
4153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return STOP;
4163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const IVec2						blockSize				= m_renderer->getBlockSize();
419efb83e1354edd463650ad0404b18e9a7efc307e4Pyry Haulos	const int						totalNumBlocks			= (int)m_blockData.size() / tcu::astc::BLOCK_SIZE_BYTES;
4203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int						numXBlocksPerImage		= de::min(m_context.getRenderTarget().getWidth(),  512) / blockSize.x();
4213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int						numYBlocksPerImage		= de::min(m_context.getRenderTarget().getHeight(), 512) / blockSize.y();
4223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int						numBlocksPerImage		= numXBlocksPerImage * numYBlocksPerImage;
4233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int						imageWidth				= numXBlocksPerImage * blockSize.x();
4243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int						imageHeight				= numYBlocksPerImage * blockSize.y();
4253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int						numBlocksRemaining		= totalNumBlocks - m_numBlocksTested;
4263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int						curNumNonDummyBlocks	= de::min(numBlocksPerImage, numBlocksRemaining);
4273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int						curNumDummyBlocks		= numBlocksPerImage - curNumNonDummyBlocks;
4283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glu::RenderContext&		renderCtx				= m_context.getRenderContext();
429becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	const tcu::RGBA					threshold				= renderCtx.getRenderTarget().getPixelFormat().getColorThreshold() + (tcu::isAstcSRGBFormat(m_format) ? tcu::RGBA(2,2,2,2) : tcu::RGBA(1,1,1,1));
4303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::CompressedTexture			compressed				(m_format, imageWidth, imageHeight);
4313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_currentIteration == 0)
4333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "Using texture of size "
4353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								<< imageWidth << "x" << imageHeight
4363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								<< ", with " << numXBlocksPerImage << " block columns and " << numYBlocksPerImage << " block rows "
4373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								<< ", with block size " << blockSize.x() << "x" << blockSize.y()
4383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< TestLog::EndMessage;
4393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
441efb83e1354edd463650ad0404b18e9a7efc307e4Pyry Haulos	DE_ASSERT(compressed.getDataSize() == numBlocksPerImage*tcu::astc::BLOCK_SIZE_BYTES);
442efb83e1354edd463650ad0404b18e9a7efc307e4Pyry Haulos	deMemcpy(compressed.getData(), &m_blockData[m_numBlocksTested*tcu::astc::BLOCK_SIZE_BYTES], curNumNonDummyBlocks*tcu::astc::BLOCK_SIZE_BYTES);
4433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (curNumDummyBlocks > 1)
444efb83e1354edd463650ad0404b18e9a7efc307e4Pyry Haulos		tcu::astc::generateDummyVoidExtentBlocks((deUint8*)compressed.getData() + curNumNonDummyBlocks*tcu::astc::BLOCK_SIZE_BYTES, curNumDummyBlocks);
4453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Create texture and render.
4473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
448becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	glu::Texture2D	texture			(renderCtx, m_context.getContextInfo(), 1, &compressed, tcu::TexDecompressionParams((m_renderer->getASTCSupport() == ASTCSUPPORTLEVEL_LDR ? tcu::TexDecompressionParams::ASTCMODE_LDR : tcu::TexDecompressionParams::ASTCMODE_HDR)));
4493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Surface			renderedFrame	(imageWidth, imageHeight);
4503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Surface			referenceFrame	(imageWidth, imageHeight);
4513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
452becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	m_renderer->render(referenceFrame, renderedFrame, texture, getUncompressedFormat(compressed.getFormat()));
4533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Compare and log.
4553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// \note Since a case can draw quite many images, only log the first iteration and failures.
4563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Surface		errorMask;
4593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		IVec2		firstFailedBlockCoord;
4603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		IVec4		maxDiff;
4613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool	compareOk = compareBlockImages(referenceFrame, renderedFrame, threshold, blockSize, curNumNonDummyBlocks, firstFailedBlockCoord, errorMask, maxDiff);
4623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (m_currentIteration == 0 || !compareOk)
4643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
4653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const char* const		imageSetName	= "ComparisonResult";
4663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const char* const		imageSetDesc	= "Comparison Result";
4673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
4693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				tcu::ScopedLogSection section(log, "Iteration " + de::toString(m_currentIteration),
4703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													"Blocks " + de::toString(m_numBlocksTested) + " to " + de::toString(m_numBlocksTested + curNumNonDummyBlocks - 1));
4713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (curNumDummyBlocks > 0)
4733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					log << TestLog::Message << "Note: Only the first " << curNumNonDummyBlocks << " blocks in the image are relevant; rest " << curNumDummyBlocks << " are dummies and not checked" << TestLog::EndMessage;
4743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (!compareOk)
4763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
4773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					log << TestLog::Message << "Image comparison failed: max difference = " << maxDiff << ", threshold = " << threshold << TestLog::EndMessage
4783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						<< TestLog::ImageSet(imageSetName, imageSetDesc)
4793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						<< TestLog::Image("Result",		"Result",		renderedFrame)
4803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						<< TestLog::Image("Reference",	"Reference",	referenceFrame)
4813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						<< TestLog::Image("ErrorMask",	"Error mask",	errorMask)
4823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						<< TestLog::EndImageSet;
4833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const int blockNdx = m_numBlocksTested + firstFailedBlockCoord.y()*numXBlocksPerImage + firstFailedBlockCoord.x();
4853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					DE_ASSERT(blockNdx < totalNumBlocks);
4863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					log << TestLog::Message << "First failed block at column " << firstFailedBlockCoord.x() << " and row " << firstFailedBlockCoord.y() << TestLog::EndMessage
488efb83e1354edd463650ad0404b18e9a7efc307e4Pyry Haulos						<< TestLog::Message << "Data of first failed block:\n" << astcBlockDataStr(&m_blockData[blockNdx*tcu::astc::BLOCK_SIZE_BYTES]) << TestLog::EndMessage;
4893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image comparison failed");
4913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					return STOP;
4923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
4933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				else
4943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
4953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					log << TestLog::ImageSet(imageSetName, imageSetDesc)
4963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						<< TestLog::Image("Result", "Result", renderedFrame)
4973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						<< TestLog::EndImageSet;
4983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
4993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
5003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (m_numBlocksTested + curNumNonDummyBlocks < totalNumBlocks)
5023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				log << TestLog::Message << "Note: not logging further images unless reference comparison fails" << TestLog::EndMessage;
5033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
5043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_currentIteration++;
5073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_numBlocksTested += curNumNonDummyBlocks;
5083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_numBlocksTested >= totalNumBlocks)
5103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(m_numBlocksTested == totalNumBlocks);
5123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
5133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return STOP;
5143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return CONTINUE;
5173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
521becd5d53015521acf7536ba754de326d8b1da2f3Mika IsojärviASTCBlockSizeRemainderCase2D::ASTCBlockSizeRemainderCase2D (Context&			context,
522becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi															const char*			name,
523becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi															const char*			description,
524becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi															CompressedTexFormat	format)
5253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCase				(context, name, description)
5263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_format				(format)
5273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_currentIteration	(0)
5283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_renderer			(new ASTCRenderer2D(context, format, deStringHash(getName())))
5293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5323c827367444ee418f129b2c238299f49d3264554Jarkko PoyryASTCBlockSizeRemainderCase2D::~ASTCBlockSizeRemainderCase2D (void)
5333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ASTCBlockSizeRemainderCase2D::deinit();
5353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5373c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ASTCBlockSizeRemainderCase2D::init (void)
5383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const IVec2 blockSize = m_renderer->getBlockSize();
5403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_renderer->initialize(MAX_NUM_BLOCKS_X*blockSize.x(), MAX_NUM_BLOCKS_Y*blockSize.y(), Vec4(1.0f), Vec4(0.0f));
5413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5433c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ASTCBlockSizeRemainderCase2D::deinit (void)
5443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_renderer->clear();
5463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5483c827367444ee418f129b2c238299f49d3264554Jarkko PoyryASTCBlockSizeRemainderCase2D::IterateResult ASTCBlockSizeRemainderCase2D::iterate (void)
5493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestLog&						log						= m_testCtx.getLog();
5513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const IVec2						blockSize				= m_renderer->getBlockSize();
5523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int						curRemainderX			= m_currentIteration % blockSize.x();
5533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int						curRemainderY			= m_currentIteration / blockSize.x();
5543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int						imageWidth				= (MAX_NUM_BLOCKS_X-1)*blockSize.x() + curRemainderX;
5553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int						imageHeight				= (MAX_NUM_BLOCKS_Y-1)*blockSize.y() + curRemainderY;
556efb83e1354edd463650ad0404b18e9a7efc307e4Pyry Haulos	const int						numBlocksX				= deDivRoundUp32(imageWidth, blockSize.x());
557efb83e1354edd463650ad0404b18e9a7efc307e4Pyry Haulos	const int						numBlocksY				= deDivRoundUp32(imageHeight, blockSize.y());
5583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int						totalNumBlocks			= numBlocksX * numBlocksY;
5593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glu::RenderContext&		renderCtx				= m_context.getRenderContext();
560becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	const tcu::RGBA					threshold				= renderCtx.getRenderTarget().getPixelFormat().getColorThreshold() + (tcu::isAstcSRGBFormat(m_format) ? tcu::RGBA(2,2,2,2) : tcu::RGBA(1,1,1,1));
5613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::CompressedTexture			compressed				(m_format, imageWidth, imageHeight);
5623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
563efb83e1354edd463650ad0404b18e9a7efc307e4Pyry Haulos	DE_ASSERT(compressed.getDataSize() == totalNumBlocks*tcu::astc::BLOCK_SIZE_BYTES);
564efb83e1354edd463650ad0404b18e9a7efc307e4Pyry Haulos	tcu::astc::generateDummyNormalBlocks((deUint8*)compressed.getData(), totalNumBlocks, blockSize.x(), blockSize.y());
5653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Create texture and render.
5673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Surface			renderedFrame	(imageWidth, imageHeight);
5693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Surface			referenceFrame	(imageWidth, imageHeight);
570becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	glu::Texture2D	texture			(renderCtx, m_context.getContextInfo(), 1, &compressed, tcu::TexDecompressionParams(m_renderer->getASTCSupport() == ASTCSUPPORTLEVEL_LDR ? tcu::TexDecompressionParams::ASTCMODE_LDR : tcu::TexDecompressionParams::ASTCMODE_HDR));
5713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
572becd5d53015521acf7536ba754de326d8b1da2f3Mika Isojärvi	m_renderer->render(referenceFrame, renderedFrame, texture, getUncompressedFormat(compressed.getFormat()));
5733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Compare and log.
5763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::ScopedLogSection section(log, "Iteration " + de::toString(m_currentIteration),
5783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										   "Remainder " + de::toString(curRemainderX) + "x" + de::toString(curRemainderY));
5793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "Using texture of size "
5813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								<< imageWidth << "x" << imageHeight
5823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								<< " and block size "
5833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								<< blockSize.x() << "x" << blockSize.y()
5843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								<< "; the x and y remainders are "
5853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								<< curRemainderX << " and " << curRemainderY << " respectively"
5863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< TestLog::EndMessage;
5873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool compareOk = tcu::pixelThresholdCompare(m_testCtx.getLog(), "ComparisonResult", "Comparison Result", referenceFrame, renderedFrame, threshold,
5893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														  m_currentIteration == 0 ? tcu::COMPARE_LOG_RESULT : tcu::COMPARE_LOG_ON_ERROR);
5903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!compareOk)
5923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
5933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image comparison failed");
5943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return STOP;
5953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
5963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_currentIteration == 0 && m_currentIteration+1 < blockSize.x()*blockSize.y())
5993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "Note: not logging further images unless reference comparison fails" << TestLog::EndMessage;
6003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_currentIteration++;
6023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_currentIteration >= blockSize.x()*blockSize.y())
6043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(m_currentIteration == blockSize.x()*blockSize.y());
6063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
6073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return STOP;
6083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return CONTINUE;
6103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // Functional
6133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // gles3
6143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // deqp
615