• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
BasicBufferCopyCase(Context & context,const char * name,const char * desc,deUint32 srcTarget,int srcSize,deUint32 srcHint,deUint32 dstTarget,int dstSize,deUint32 dstHint,int copySrcOffset,int copyDstOffset,int copySize,VerifyType verifyType)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 
iterate(void)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:
SingleBufferCopyCase(Context & context,const char * name,const char * desc,deUint32 srcTarget,deUint32 dstTarget,deUint32 hint,VerifyType verifyType)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 
iterate(void)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 
BufferCopyTests(Context & context)230 BufferCopyTests::BufferCopyTests (Context& context)
231 	: TestCaseGroup(context, "copy", "Buffer copy tests")
232 {
233 }
234 
~BufferCopyTests(void)235 BufferCopyTests::~BufferCopyTests (void)
236 {
237 }
238 
init(void)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