Home | History | Annotate | Download | only in functional
      1 /*-------------------------------------------------------------------------
      2  * drawElements Quality Program OpenGL ES 3.0 Module
      3  * -------------------------------------------------
      4  *
      5  * Copyright 2014 The Android Open Source Project
      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 Buffer copying tests.
     22  *//*--------------------------------------------------------------------*/
     23 
     24 #include "es3fBufferCopyTests.hpp"
     25 #include "glsBufferTestUtil.hpp"
     26 #include "tcuTestLog.hpp"
     27 #include "deMemory.h"
     28 #include "deString.h"
     29 #include "glwEnums.hpp"
     30 #include "glwFunctions.hpp"
     31 
     32 #include <algorithm>
     33 
     34 using std::vector;
     35 using std::string;
     36 using tcu::TestLog;
     37 
     38 namespace deqp
     39 {
     40 namespace gles3
     41 {
     42 namespace Functional
     43 {
     44 
     45 using namespace gls::BufferTestUtil;
     46 
     47 class BasicBufferCopyCase : public BufferCase
     48 {
     49 public:
     50 	BasicBufferCopyCase (Context&		context,
     51 						 const char*	name,
     52 						 const char*	desc,
     53 						 deUint32		srcTarget,
     54 						 int			srcSize,
     55 						 deUint32		srcHint,
     56 						 deUint32		dstTarget,
     57 						 int			dstSize,
     58 						 deUint32		dstHint,
     59 						 int			copySrcOffset,
     60 						 int			copyDstOffset,
     61 						 int			copySize,
     62 						 VerifyType		verifyType)
     63 		: BufferCase		(context.getTestContext(), context.getRenderContext(), name, desc)
     64 		, m_srcTarget		(srcTarget)
     65 		, m_srcSize			(srcSize)
     66 		, m_srcHint			(srcHint)
     67 		, m_dstTarget		(dstTarget)
     68 		, m_dstSize			(dstSize)
     69 		, m_dstHint			(dstHint)
     70 		, m_copySrcOffset	(copySrcOffset)
     71 		, m_copyDstOffset	(copyDstOffset)
     72 		, m_copySize		(copySize)
     73 		, m_verifyType		(verifyType)
     74 	{
     75 		DE_ASSERT(de::inBounds(m_copySrcOffset, 0, m_srcSize) && de::inRange(m_copySrcOffset+m_copySize, m_copySrcOffset, m_srcSize));
     76 		DE_ASSERT(de::inBounds(m_copyDstOffset, 0, m_dstSize) && de::inRange(m_copyDstOffset+m_copySize, m_copyDstOffset, m_dstSize));
     77 	}
     78 
     79 	IterateResult iterate (void)
     80 	{
     81 		BufferVerifier	verifier	(m_renderCtx, m_testCtx.getLog(), m_verifyType);
     82 		ReferenceBuffer	srcRef;
     83 		ReferenceBuffer	dstRef;
     84 		deUint32		srcBuf		= 0;
     85 		deUint32		dstBuf		= 0;
     86 		deUint32		srcSeed		= deStringHash(getName()) ^ 0xabcd;
     87 		deUint32		dstSeed		= deStringHash(getName()) ^ 0xef01;
     88 		bool			isOk		= true;
     89 
     90 		srcRef.setSize(m_srcSize);
     91 		fillWithRandomBytes(srcRef.getPtr(), m_srcSize, srcSeed);
     92 
     93 		dstRef.setSize(m_dstSize);
     94 		fillWithRandomBytes(dstRef.getPtr(), m_dstSize, dstSeed);
     95 
     96 		// Create source buffer and fill with data.
     97 		srcBuf = genBuffer();
     98 		glBindBuffer(m_srcTarget, srcBuf);
     99 		glBufferData(m_srcTarget, m_srcSize, srcRef.getPtr(), m_srcHint);
    100 		GLU_CHECK_MSG("glBufferData");
    101 
    102 		// Create destination buffer and fill with data.
    103 		dstBuf = genBuffer();
    104 		glBindBuffer(m_dstTarget, dstBuf);
    105 		glBufferData(m_dstTarget, m_dstSize, dstRef.getPtr(), m_dstHint);
    106 		GLU_CHECK_MSG("glBufferData");
    107 
    108 		// Verify both buffers before executing copy.
    109 		isOk = verifier.verify(srcBuf, srcRef.getPtr(), 0, m_srcSize, m_srcTarget) && isOk;
    110 		isOk = verifier.verify(dstBuf, dstRef.getPtr(), 0, m_dstSize, m_dstTarget) && isOk;
    111 
    112 		// Execute copy.
    113 		deMemcpy(dstRef.getPtr()+m_copyDstOffset, srcRef.getPtr()+m_copySrcOffset, m_copySize);
    114 
    115 		glBindBuffer(m_srcTarget, srcBuf);
    116 		glBindBuffer(m_dstTarget, dstBuf);
    117 		glCopyBufferSubData(m_srcTarget, m_dstTarget, m_copySrcOffset, m_copyDstOffset, m_copySize);
    118 		GLU_CHECK_MSG("glCopyBufferSubData");
    119 
    120 		// Verify both buffers after copy.
    121 		isOk = verifier.verify(srcBuf, srcRef.getPtr(), 0, m_srcSize, m_srcTarget) && isOk;
    122 		isOk = verifier.verify(dstBuf, dstRef.getPtr(), 0, m_dstSize, m_dstTarget) && isOk;
    123 
    124 		m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS	: QP_TEST_RESULT_FAIL,
    125 								isOk ? "Pass"				: "Buffer verification failed");
    126 		return STOP;
    127 	}
    128 
    129 private:
    130 	deUint32	m_srcTarget;
    131 	int			m_srcSize;
    132 	deUint32	m_srcHint;
    133 
    134 	deUint32	m_dstTarget;
    135 	int			m_dstSize;
    136 	deUint32	m_dstHint;
    137 
    138 	int			m_copySrcOffset;
    139 	int			m_copyDstOffset;
    140 	int			m_copySize;
    141 
    142 	VerifyType	m_verifyType;
    143 };
    144 
    145 // Case B: same buffer, take range as parameter
    146 
    147 class SingleBufferCopyCase : public BufferCase
    148 {
    149 public:
    150 	SingleBufferCopyCase (Context&		context,
    151 						  const char*	name,
    152 						  const char*	desc,
    153 						  deUint32		srcTarget,
    154 						  deUint32		dstTarget,
    155 						  deUint32		hint,
    156 						  VerifyType	verifyType)
    157 		: BufferCase		(context.getTestContext(), context.getRenderContext(), name, desc)
    158 		, m_srcTarget		(srcTarget)
    159 		, m_dstTarget		(dstTarget)
    160 		, m_hint			(hint)
    161 		, m_verifyType		(verifyType)
    162 	{
    163 	}
    164 
    165 	IterateResult iterate (void)
    166 	{
    167 		const int		size		= 1000;
    168 		BufferVerifier	verifier	(m_renderCtx, m_testCtx.getLog(), m_verifyType);
    169 		ReferenceBuffer	ref;
    170 		deUint32		buf			= 0;
    171 		deUint32		baseSeed	= deStringHash(getName());
    172 		bool			isOk		= true;
    173 
    174 		ref.setSize(size);
    175 
    176 		// Create buffer.
    177 		buf = genBuffer();
    178 		glBindBuffer(m_srcTarget, buf);
    179 
    180 		static const struct
    181 		{
    182 			int				srcOffset;
    183 			int				dstOffset;
    184 			int				copySize;
    185 		} copyRanges[] =
    186 		{
    187 			{ 57,		701,	101 },	// Non-adjecent, from low to high.
    188 			{ 640,		101,	101 },	// Non-adjecent, from high to low.
    189 			{ 0,		500,	500 },	// Lower half to upper half.
    190 			{ 500,		0,		500 }	// Upper half to lower half.
    191 		};
    192 
    193 		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(copyRanges) && isOk; ndx++)
    194 		{
    195 			int	srcOffset	= copyRanges[ndx].srcOffset;
    196 			int	dstOffset	= copyRanges[ndx].dstOffset;
    197 			int	copySize	= copyRanges[ndx].copySize;
    198 
    199 			fillWithRandomBytes(ref.getPtr(), size, baseSeed ^ deInt32Hash(ndx));
    200 
    201 			// Fill with data.
    202 			glBindBuffer(m_srcTarget, buf);
    203 			glBufferData(m_srcTarget, size, ref.getPtr(), m_hint);
    204 			GLU_CHECK_MSG("glBufferData");
    205 
    206 			// Execute copy.
    207 			deMemcpy(ref.getPtr()+dstOffset, ref.getPtr()+srcOffset, copySize);
    208 
    209 			glBindBuffer(m_dstTarget, buf);
    210 			glCopyBufferSubData(m_srcTarget, m_dstTarget, srcOffset, dstOffset, copySize);
    211 			GLU_CHECK_MSG("glCopyBufferSubData");
    212 
    213 			// Verify buffer after copy.
    214 			isOk = verifier.verify(buf, ref.getPtr(), 0, size, m_dstTarget) && isOk;
    215 		}
    216 
    217 		m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS	: QP_TEST_RESULT_FAIL,
    218 								isOk ? "Pass"				: "Buffer verification failed");
    219 		return STOP;
    220 	}
    221 
    222 private:
    223 	deUint32	m_srcTarget;
    224 	deUint32	m_dstTarget;
    225 	deUint32	m_hint;
    226 
    227 	VerifyType	m_verifyType;
    228 };
    229 
    230 BufferCopyTests::BufferCopyTests (Context& context)
    231 	: TestCaseGroup(context, "copy", "Buffer copy tests")
    232 {
    233 }
    234 
    235 BufferCopyTests::~BufferCopyTests (void)
    236 {
    237 }
    238 
    239 void BufferCopyTests::init (void)
    240 {
    241 	static const deUint32 bufferTargets[] =
    242 	{
    243 		GL_ARRAY_BUFFER,
    244 		GL_COPY_READ_BUFFER,
    245 		GL_COPY_WRITE_BUFFER,
    246 		GL_ELEMENT_ARRAY_BUFFER,
    247 		GL_PIXEL_PACK_BUFFER,
    248 		GL_PIXEL_UNPACK_BUFFER,
    249 		GL_TRANSFORM_FEEDBACK_BUFFER,
    250 		GL_UNIFORM_BUFFER
    251 	};
    252 
    253 	// .basic
    254 	{
    255 		tcu::TestCaseGroup* basicGroup = new tcu::TestCaseGroup(m_testCtx, "basic", "Basic buffer copy cases");
    256 		addChild(basicGroup);
    257 
    258 		for (int srcTargetNdx = 0; srcTargetNdx < DE_LENGTH_OF_ARRAY(bufferTargets); srcTargetNdx++)
    259 		{
    260 			for (int dstTargetNdx = 0; dstTargetNdx < DE_LENGTH_OF_ARRAY(bufferTargets); dstTargetNdx++)
    261 			{
    262 				if (srcTargetNdx == dstTargetNdx)
    263 					continue;
    264 
    265 				deUint32		srcTarget		= bufferTargets[srcTargetNdx];
    266 				deUint32		dstTarget		= bufferTargets[dstTargetNdx];
    267 				const int		size			= 1017;
    268 				const deUint32	hint			= GL_STATIC_DRAW;
    269 				VerifyType		verify			= VERIFY_AS_VERTEX_ARRAY;
    270 				string			name			= string(getBufferTargetName(srcTarget)) + "_" + getBufferTargetName(dstTarget);
    271 
    272 				basicGroup->addChild(new BasicBufferCopyCase(m_context, name.c_str(), "", srcTarget, size, hint, dstTarget, size, hint, 0, 0, size, verify));
    273 			}
    274 		}
    275 	}
    276 
    277 	// .subrange
    278 	{
    279 		tcu::TestCaseGroup* subrangeGroup = new tcu::TestCaseGroup(m_testCtx, "subrange", "Buffer subrange copy tests");
    280 		addChild(subrangeGroup);
    281 
    282 		static const struct
    283 		{
    284 			const char*		name;
    285 			int				srcSize;
    286 			int				dstSize;
    287 			int				srcOffset;
    288 			int				dstOffset;
    289 			int				copySize;
    290 		} cases[] =
    291 		{
    292 			//						srcSize		dstSize		srcOffs		dstOffs		copySize
    293 			{ "middle",				1000,		1000,		250,		250,		500 },
    294 			{ "small_to_large",		100,		1000,		0,			409,		100 },
    295 			{ "large_to_small",		1000,		100,		409,		0,			100 },
    296 			{ "low_to_high_1",		1000,		1000,		0,			500,		500 },
    297 			{ "low_to_high_2",		997,		1027,		0,			701,		111 },
    298 			{ "high_to_low_1",		1000,		1000,		500,		0,			500 },
    299 			{ "high_to_low_2",		1027,		997,		701,		17,			111 }
    300 		};
    301 
    302 		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(cases); ndx++)
    303 		{
    304 			deUint32		srcTarget		= GL_COPY_READ_BUFFER;
    305 			deUint32		dstTarget		= GL_COPY_WRITE_BUFFER;
    306 			deUint32		hint			= GL_STATIC_DRAW;
    307 			VerifyType		verify			= VERIFY_AS_VERTEX_ARRAY;
    308 
    309 			subrangeGroup->addChild(new BasicBufferCopyCase(m_context, cases[ndx].name, "",
    310 															srcTarget, cases[ndx].srcSize, hint,
    311 															dstTarget, cases[ndx].dstSize, hint,
    312 															cases[ndx].srcOffset, cases[ndx].dstOffset, cases[ndx].copySize,
    313 															verify));
    314 		}
    315 	}
    316 
    317 	// .single_buffer
    318 	{
    319 		tcu::TestCaseGroup* singleBufGroup = new tcu::TestCaseGroup(m_testCtx, "single_buffer", "Copies within single buffer");
    320 		addChild(singleBufGroup);
    321 
    322 		for (int srcTargetNdx = 0; srcTargetNdx < DE_LENGTH_OF_ARRAY(bufferTargets); srcTargetNdx++)
    323 		{
    324 			for (int dstTargetNdx = 0; dstTargetNdx < DE_LENGTH_OF_ARRAY(bufferTargets); dstTargetNdx++)
    325 			{
    326 				if (srcTargetNdx == dstTargetNdx)
    327 					continue;
    328 
    329 				deUint32		srcTarget		= bufferTargets[srcTargetNdx];
    330 				deUint32		dstTarget		= bufferTargets[dstTargetNdx];
    331 				const deUint32	hint			= GL_STATIC_DRAW;
    332 				VerifyType		verify			= VERIFY_AS_VERTEX_ARRAY;
    333 				string			name			= string(getBufferTargetName(srcTarget)) + "_" + getBufferTargetName(dstTarget);
    334 
    335 				singleBufGroup->addChild(new SingleBufferCopyCase(m_context, name.c_str(), "", srcTarget, dstTarget, hint, verify));
    336 			}
    337 		}
    338 	}
    339 }
    340 
    341 } // Functional
    342 } // gles3
    343 } // deqp
    344