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 map tests.
     22  *//*--------------------------------------------------------------------*/
     23 
     24 #include "es3fBufferMapTests.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::set;
     35 using std::vector;
     36 using std::string;
     37 using tcu::TestLog;
     38 
     39 namespace deqp
     40 {
     41 namespace gles3
     42 {
     43 namespace Functional
     44 {
     45 
     46 using namespace gls::BufferTestUtil;
     47 
     48 // Test cases.
     49 
     50 class BufferMapReadCase : public BufferCase
     51 {
     52 public:
     53 	BufferMapReadCase (Context& context, const char* name, const char* desc, deUint32 bufferTarget, deUint32 usage, int bufferSize, int mapOffset, int mapSize, WriteType write)
     54 		: BufferCase		(context.getTestContext(), context.getRenderContext(), name, desc)
     55 		, m_bufferTarget	(bufferTarget)
     56 		, m_usage			(usage)
     57 		, m_bufferSize		(bufferSize)
     58 		, m_mapOffset		(mapOffset)
     59 		, m_mapSize			(mapSize)
     60 		, m_write			(write)
     61 	{
     62 	}
     63 
     64 	IterateResult iterate (void)
     65 	{
     66 		TestLog&		log			= m_testCtx.getLog();
     67 		deUint32		dataSeed	= deStringHash(getName());
     68 		ReferenceBuffer	refBuf;
     69 		BufferWriter	writer		(m_renderCtx, m_testCtx.getLog(), m_write);
     70 		bool			isOk		= false;
     71 
     72 		// Setup reference data.
     73 		refBuf.setSize(m_bufferSize);
     74 		fillWithRandomBytes(refBuf.getPtr(), m_bufferSize, dataSeed);
     75 
     76 		deUint32 buf = genBuffer();
     77 		glBindBuffer(m_bufferTarget, buf);
     78 		glBufferData(m_bufferTarget, m_bufferSize, DE_NULL, m_usage);
     79 		writer.write(buf, 0, m_bufferSize, refBuf.getPtr(), m_bufferTarget);
     80 
     81 		glBindBuffer(m_bufferTarget, buf);
     82 		void* ptr = glMapBufferRange(m_bufferTarget, m_mapOffset, m_mapSize, GL_MAP_READ_BIT);
     83 		GLU_CHECK_MSG("glMapBufferRange");
     84 		TCU_CHECK(ptr);
     85 
     86 		isOk = compareByteArrays(log, (const deUint8*)ptr, refBuf.getPtr(m_mapOffset), m_mapSize);
     87 
     88 		glUnmapBuffer(m_bufferTarget);
     89 		GLU_CHECK_MSG("glUnmapBuffer");
     90 
     91 		deleteBuffer(buf);
     92 
     93 		m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS	: QP_TEST_RESULT_FAIL,
     94 								isOk ? "Pass"				: "Buffer verification failed");
     95 		return STOP;
     96 	}
     97 
     98 private:
     99 	deUint32		m_bufferTarget;
    100 	deUint32		m_usage;
    101 	int				m_bufferSize;
    102 	int				m_mapOffset;
    103 	int				m_mapSize;
    104 	WriteType		m_write;
    105 };
    106 
    107 class BufferMapWriteCase : public BufferCase
    108 {
    109 public:
    110 	BufferMapWriteCase (Context& context, const char* name, const char* desc, deUint32 bufferTarget, deUint32 usage, int size, VerifyType verify)
    111 		: BufferCase		(context.getTestContext(), context.getRenderContext(), name, desc)
    112 		, m_bufferTarget	(bufferTarget)
    113 		, m_usage			(usage)
    114 		, m_size			(size)
    115 		, m_verify			(verify)
    116 	{
    117 	}
    118 
    119 	IterateResult iterate (void)
    120 	{
    121 		deUint32		dataSeed	= deStringHash(getName());
    122 		ReferenceBuffer	refBuf;
    123 		BufferVerifier	verifier	(m_renderCtx, m_testCtx.getLog(), m_verify);
    124 
    125 		// Setup reference data.
    126 		refBuf.setSize(m_size);
    127 		fillWithRandomBytes(refBuf.getPtr(), m_size, dataSeed);
    128 
    129 		deUint32 buf = genBuffer();
    130 		glBindBuffer(m_bufferTarget, buf);
    131 		glBufferData(m_bufferTarget, m_size, DE_NULL, m_usage);
    132 
    133 		void* ptr = glMapBufferRange(m_bufferTarget, 0, m_size, GL_MAP_WRITE_BIT);
    134 		GLU_CHECK_MSG("glMapBufferRange");
    135 		TCU_CHECK(ptr);
    136 
    137 		fillWithRandomBytes((deUint8*)ptr, m_size, dataSeed);
    138 		glUnmapBuffer(m_bufferTarget);
    139 		GLU_CHECK_MSG("glUnmapBuffer");
    140 
    141 		bool isOk = verifier.verify(buf, refBuf.getPtr(), 0, m_size, m_bufferTarget);
    142 		deleteBuffer(buf);
    143 
    144 		m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS	: QP_TEST_RESULT_FAIL,
    145 								isOk ? "Pass"				: "Buffer verification failed");
    146 		return STOP;
    147 	}
    148 
    149 private:
    150 	deUint32		m_bufferTarget;
    151 	deUint32		m_usage;
    152 	int				m_size;
    153 	VerifyType		m_verify;
    154 };
    155 
    156 class BufferPartialMapWriteCase : public BufferCase
    157 {
    158 public:
    159 	BufferPartialMapWriteCase (Context& context, const char* name, const char* desc, deUint32 bufferTarget, deUint32 usage, int bufferSize, int mapOffset, int mapSize, VerifyType verify)
    160 		: BufferCase		(context.getTestContext(), context.getRenderContext(), name, desc)
    161 		, m_bufferTarget	(bufferTarget)
    162 		, m_usage			(usage)
    163 		, m_bufferSize		(bufferSize)
    164 		, m_mapOffset		(mapOffset)
    165 		, m_mapSize			(mapSize)
    166 		, m_verify			(verify)
    167 	{
    168 	}
    169 
    170 	IterateResult iterate (void)
    171 	{
    172 		deUint32		dataSeed	= deStringHash(getName());
    173 		ReferenceBuffer	refBuf;
    174 		BufferVerifier	verifier	(m_renderCtx, m_testCtx.getLog(), m_verify);
    175 
    176 		// Setup reference data.
    177 		refBuf.setSize(m_bufferSize);
    178 		fillWithRandomBytes(refBuf.getPtr(), m_bufferSize, dataSeed);
    179 
    180 		deUint32 buf = genBuffer();
    181 		glBindBuffer(m_bufferTarget, buf);
    182 		glBufferData(m_bufferTarget, m_bufferSize, refBuf.getPtr(), m_usage);
    183 
    184 		// Do reference map.
    185 		fillWithRandomBytes(refBuf.getPtr(m_mapOffset), m_mapSize, dataSeed&0xabcdef);
    186 
    187 		void* ptr = glMapBufferRange(m_bufferTarget, m_mapOffset, m_mapSize, GL_MAP_WRITE_BIT);
    188 		GLU_CHECK_MSG("glMapBufferRange");
    189 		TCU_CHECK(ptr);
    190 
    191 		deMemcpy(ptr, refBuf.getPtr(m_mapOffset), m_mapSize);
    192 		glUnmapBuffer(m_bufferTarget);
    193 		GLU_CHECK_MSG("glUnmapBuffer");
    194 
    195 		bool isOk = verifier.verify(buf, refBuf.getPtr(), 0, m_bufferSize, m_bufferTarget);
    196 		deleteBuffer(buf);
    197 
    198 		m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS	: QP_TEST_RESULT_FAIL,
    199 								isOk ? "Pass"				: "Buffer verification failed");
    200 		return STOP;
    201 	}
    202 
    203 private:
    204 	deUint32		m_bufferTarget;
    205 	deUint32		m_usage;
    206 	int				m_bufferSize;
    207 	int				m_mapOffset;
    208 	int				m_mapSize;
    209 	VerifyType		m_verify;
    210 };
    211 
    212 class BufferMapInvalidateCase : public BufferCase
    213 {
    214 public:
    215 	BufferMapInvalidateCase (Context& context, const char* name, const char* desc, deUint32 bufferTarget, deUint32 usage, bool partialWrite, VerifyType verify)
    216 		: BufferCase		(context.getTestContext(), context.getRenderContext(), name, desc)
    217 		, m_bufferTarget	(bufferTarget)
    218 		, m_usage			(usage)
    219 		, m_partialWrite	(partialWrite)
    220 		, m_verify			(verify)
    221 	{
    222 	}
    223 
    224 	IterateResult iterate (void)
    225 	{
    226 		deUint32		dataSeed		= deStringHash(getName());
    227 		deUint32		buf				= 0;
    228 		ReferenceBuffer	refBuf;
    229 		BufferVerifier	verifier		(m_renderCtx, m_testCtx.getLog(), m_verify);
    230 		const int		bufferSize		= 1300;
    231 		const int		mapOffset		= 200;
    232 		const int		mapSize			= 1011;
    233 		const int		mapWriteOffs	= m_partialWrite ? 91 : 0;
    234 		const int		verifyOffset	= mapOffset+mapWriteOffs;
    235 		const int		verifySize		= mapSize-mapWriteOffs;
    236 
    237 		// Setup reference data.
    238 		refBuf.setSize(bufferSize);
    239 		fillWithRandomBytes(refBuf.getPtr(), bufferSize, dataSeed);
    240 
    241 		buf = genBuffer();
    242 		glBindBuffer(m_bufferTarget, buf);
    243 		glBufferData(m_bufferTarget, bufferSize, refBuf.getPtr(), m_usage);
    244 
    245 		// Do reference map.
    246 		fillWithRandomBytes(refBuf.getPtr(mapOffset+mapWriteOffs), mapSize-mapWriteOffs, dataSeed&0xabcdef);
    247 
    248 		void* ptr = glMapBufferRange(m_bufferTarget, mapOffset, mapSize, GL_MAP_WRITE_BIT|GL_MAP_INVALIDATE_BUFFER_BIT);
    249 		GLU_CHECK_MSG("glMapBufferRange");
    250 		TCU_CHECK(ptr);
    251 
    252 		deMemcpy((deUint8*)ptr+mapWriteOffs, refBuf.getPtr(mapOffset+mapWriteOffs), mapSize-mapWriteOffs);
    253 		glUnmapBuffer(m_bufferTarget);
    254 		GLU_CHECK_MSG("glUnmapBuffer");
    255 
    256 		bool isOk = verifier.verify(buf, refBuf.getPtr(), verifyOffset, verifySize, m_bufferTarget);
    257 		deleteBuffer(buf);
    258 
    259 		m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS	: QP_TEST_RESULT_FAIL,
    260 								isOk ? "Pass"				: "Buffer verification failed");
    261 		return STOP;
    262 	}
    263 
    264 private:
    265 	deUint32		m_bufferTarget;
    266 	deUint32		m_usage;
    267 	bool			m_partialWrite;
    268 	VerifyType		m_verify;
    269 };
    270 
    271 class BufferMapPartialInvalidateCase : public BufferCase
    272 {
    273 public:
    274 	BufferMapPartialInvalidateCase (Context& context, const char* name, const char* desc, deUint32 bufferTarget, deUint32 usage, bool partialWrite, VerifyType verify)
    275 		: BufferCase		(context.getTestContext(), context.getRenderContext(), name, desc)
    276 		, m_bufferTarget	(bufferTarget)
    277 		, m_usage			(usage)
    278 		, m_partialWrite	(partialWrite)
    279 		, m_verify			(verify)
    280 	{
    281 	}
    282 
    283 	IterateResult iterate (void)
    284 	{
    285 		deUint32		dataSeed		= deStringHash(getName());
    286 		deUint32		buf				= 0;
    287 		ReferenceBuffer	refBuf;
    288 		BufferVerifier	verifier		(m_renderCtx, m_testCtx.getLog(), m_verify);
    289 		const int		bufferSize		= 1300;
    290 		const int		mapOffset		= 200;
    291 		const int		mapSize			= 1011;
    292 		const int		mapWriteOffs	= m_partialWrite ? 91						: 0;
    293 		const int		verifyOffset	= m_partialWrite ? mapOffset+mapWriteOffs	: 0;
    294 		const int		verifySize		= bufferSize-verifyOffset;
    295 
    296 		// Setup reference data.
    297 		refBuf.setSize(bufferSize);
    298 		fillWithRandomBytes(refBuf.getPtr(), bufferSize, dataSeed);
    299 
    300 		buf = genBuffer();
    301 		glBindBuffer(m_bufferTarget, buf);
    302 		glBufferData(m_bufferTarget, bufferSize, refBuf.getPtr(), m_usage);
    303 
    304 		// Do reference map.
    305 		fillWithRandomBytes(refBuf.getPtr(mapOffset+mapWriteOffs), mapSize-mapWriteOffs, dataSeed&0xabcdef);
    306 
    307 		void* ptr = glMapBufferRange(m_bufferTarget, mapOffset, mapSize, GL_MAP_WRITE_BIT|GL_MAP_INVALIDATE_RANGE_BIT);
    308 		GLU_CHECK_MSG("glMapBufferRange");
    309 		TCU_CHECK(ptr);
    310 
    311 		deMemcpy((deUint8*)ptr+mapWriteOffs, refBuf.getPtr(mapOffset+mapWriteOffs), mapSize-mapWriteOffs);
    312 		glUnmapBuffer(m_bufferTarget);
    313 		GLU_CHECK_MSG("glUnmapBuffer");
    314 
    315 		bool isOk = verifier.verify(buf, refBuf.getPtr(), verifyOffset, verifySize, m_bufferTarget);
    316 		deleteBuffer(buf);
    317 
    318 		m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS	: QP_TEST_RESULT_FAIL,
    319 								isOk ? "Pass"				: "Buffer verification failed");
    320 		return STOP;
    321 	}
    322 
    323 private:
    324 	deUint32		m_bufferTarget;
    325 	deUint32		m_usage;
    326 	bool			m_partialWrite;
    327 	VerifyType		m_verify;
    328 };
    329 
    330 class BufferMapExplicitFlushCase : public BufferCase
    331 {
    332 public:
    333 	BufferMapExplicitFlushCase (Context& context, const char* name, const char* desc, deUint32 bufferTarget, deUint32 usage, bool partialWrite, VerifyType verify)
    334 		: BufferCase		(context.getTestContext(), context.getRenderContext(), name, desc)
    335 		, m_bufferTarget	(bufferTarget)
    336 		, m_usage			(usage)
    337 		, m_partialWrite	(partialWrite)
    338 		, m_verify			(verify)
    339 	{
    340 	}
    341 
    342 	IterateResult iterate (void)
    343 	{
    344 		deUint32		dataSeed		= deStringHash(getName());
    345 		deUint32		buf				= 0;
    346 		ReferenceBuffer	refBuf;
    347 		BufferVerifier	verifier		(m_renderCtx, m_testCtx.getLog(), m_verify);
    348 		const int		bufferSize		= 1300;
    349 		const int		mapOffset		= 200;
    350 		const int		mapSize			= 1011;
    351 		const int		sliceAOffs		= m_partialWrite ? 1		: 0;
    352 		const int		sliceASize		= m_partialWrite ? 96		: 473;
    353 		const int		sliceBOffs		= m_partialWrite ? 503		: sliceAOffs+sliceASize;
    354 		const int		sliceBSize		= mapSize-sliceBOffs;
    355 		bool			isOk			= true;
    356 
    357 		// Setup reference data.
    358 		refBuf.setSize(bufferSize);
    359 		fillWithRandomBytes(refBuf.getPtr(), bufferSize, dataSeed);
    360 
    361 		buf = genBuffer();
    362 		glBindBuffer(m_bufferTarget, buf);
    363 		glBufferData(m_bufferTarget, bufferSize, refBuf.getPtr(), m_usage);
    364 
    365 		// Do reference map.
    366 		fillWithRandomBytes(refBuf.getPtr(mapOffset), mapSize, dataSeed&0xabcdef);
    367 
    368 		void* ptr = glMapBufferRange(m_bufferTarget, mapOffset, mapSize, GL_MAP_WRITE_BIT|GL_MAP_FLUSH_EXPLICIT_BIT);
    369 		GLU_CHECK_MSG("glMapBufferRange");
    370 		TCU_CHECK(ptr);
    371 
    372 		deMemcpy(ptr, refBuf.getPtr(mapOffset), mapSize);
    373 
    374 		glFlushMappedBufferRange(m_bufferTarget, sliceAOffs, sliceASize);
    375 		GLU_CHECK_MSG("glFlushMappedBufferRange");
    376 		glFlushMappedBufferRange(m_bufferTarget, sliceBOffs, sliceBSize);
    377 		GLU_CHECK_MSG("glFlushMappedBufferRange");
    378 
    379 		glUnmapBuffer(m_bufferTarget);
    380 		GLU_CHECK_MSG("glUnmapBuffer");
    381 
    382 		if (m_partialWrite)
    383 		{
    384 			if (!verifier.verify(buf, refBuf.getPtr(), mapOffset+sliceAOffs, sliceASize, m_bufferTarget))
    385 				isOk = false;
    386 
    387 			if (!verifier.verify(buf, refBuf.getPtr(), mapOffset+sliceBOffs, sliceBSize, m_bufferTarget))
    388 				isOk = false;
    389 		}
    390 		else
    391 		{
    392 			if (!verifier.verify(buf, refBuf.getPtr(), mapOffset, mapSize, m_bufferTarget))
    393 				isOk = false;
    394 		}
    395 
    396 		deleteBuffer(buf);
    397 
    398 		m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS	: QP_TEST_RESULT_FAIL,
    399 								isOk ? "Pass"				: "Buffer verification failed");
    400 		return STOP;
    401 	}
    402 
    403 private:
    404 	deUint32		m_bufferTarget;
    405 	deUint32		m_usage;
    406 	bool			m_partialWrite;
    407 	VerifyType		m_verify;
    408 };
    409 
    410 class BufferMapUnsyncWriteCase : public BufferCase
    411 {
    412 public:
    413 	BufferMapUnsyncWriteCase (Context& context, const char* name, const char* desc, deUint32 bufferTarget, deUint32 usage)
    414 		: BufferCase		(context.getTestContext(), context.getRenderContext(), name, desc)
    415 		, m_bufferTarget	(bufferTarget)
    416 		, m_usage			(usage)
    417 	{
    418 	}
    419 
    420 	IterateResult iterate (void)
    421 	{
    422 		VertexArrayVerifier	verifier	(m_renderCtx, m_testCtx.getLog());
    423 		deUint32			dataSeed	= deStringHash(getName());
    424 		ReferenceBuffer		refBuf;
    425 		deUint32			buf			= 0;
    426 		bool				isOk		= true;
    427 		const int			size		= 1200;
    428 
    429 		// Setup reference data.
    430 		refBuf.setSize(size);
    431 		fillWithRandomBytes(refBuf.getPtr(), size, dataSeed);
    432 
    433 		buf = genBuffer();
    434 		glBindBuffer(m_bufferTarget, buf);
    435 		glBufferData(m_bufferTarget, size, refBuf.getPtr(), m_usage);
    436 
    437 		// Use for rendering.
    438 		if (!verifier.verify(buf, refBuf.getPtr(), 0, size))
    439 			isOk = false;
    440 		// \note ReadPixels() implies Finish
    441 
    442 		glBindBuffer(m_bufferTarget, buf);
    443 		void* ptr = glMapBufferRange(m_bufferTarget, 0, size, GL_MAP_WRITE_BIT|GL_MAP_UNSYNCHRONIZED_BIT);
    444 		GLU_CHECK_MSG("glMapBufferRange");
    445 		TCU_CHECK(ptr);
    446 
    447 		fillWithRandomBytes(refBuf.getPtr(), size, dataSeed&0xabcdef);
    448 		deMemcpy(ptr, refBuf.getPtr(), size);
    449 
    450 		glUnmapBuffer(m_bufferTarget);
    451 		GLU_CHECK_MSG("glUnmapBuffer");
    452 
    453 		// Synchronize.
    454 		glFinish();
    455 
    456 		if (!verifier.verify(buf, refBuf.getPtr(), 0, size))
    457 			isOk = false;
    458 
    459 		deleteBuffer(buf);
    460 
    461 		m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS	: QP_TEST_RESULT_FAIL,
    462 								isOk ? "Pass"				: "Buffer verification failed");
    463 		return STOP;
    464 	}
    465 
    466 private:
    467 	deUint32		m_bufferTarget;
    468 	deUint32		m_usage;
    469 };
    470 
    471 class BufferMapReadWriteCase : public BufferCase
    472 {
    473 public:
    474 	BufferMapReadWriteCase (Context& context, const char* name, const char* desc, deUint32 bufferTarget, deUint32 usage, int bufferSize, int mapOffset, int mapSize, VerifyType verify)
    475 		: BufferCase		(context.getTestContext(), context.getRenderContext(), name, desc)
    476 		, m_bufferTarget	(bufferTarget)
    477 		, m_usage			(usage)
    478 		, m_bufferSize		(bufferSize)
    479 		, m_mapOffset		(mapOffset)
    480 		, m_mapSize			(mapSize)
    481 		, m_verify			(verify)
    482 	{
    483 	}
    484 
    485 	IterateResult iterate (void)
    486 	{
    487 		TestLog&		log			= m_testCtx.getLog();
    488 		deUint32		dataSeed	= deStringHash(getName());
    489 		deUint32		buf			= 0;
    490 		ReferenceBuffer	refBuf;
    491 		BufferVerifier	verifier	(m_renderCtx, m_testCtx.getLog(), m_verify);
    492 		bool			isOk		= true;
    493 
    494 		// Setup reference data.
    495 		refBuf.setSize(m_bufferSize);
    496 		fillWithRandomBytes(refBuf.getPtr(), m_bufferSize, dataSeed);
    497 
    498 		buf = genBuffer();
    499 		glBindBuffer(m_bufferTarget, buf);
    500 		glBufferData(m_bufferTarget, m_bufferSize, refBuf.getPtr(), m_usage);
    501 
    502 		// Verify before mapping.
    503 		if (!verifier.verify(buf, refBuf.getPtr(), 0, m_bufferSize, m_bufferTarget))
    504 			isOk = false;
    505 
    506 		glBindBuffer(m_bufferTarget, buf);
    507 		void* ptr = glMapBufferRange(m_bufferTarget, m_mapOffset, m_mapSize, GL_MAP_READ_BIT|GL_MAP_WRITE_BIT);
    508 		GLU_CHECK_MSG("glMapBufferRange");
    509 		TCU_CHECK(ptr);
    510 
    511 		// Compare mapped ptr.
    512 		if (!compareByteArrays(log, (const deUint8*)ptr, refBuf.getPtr(m_mapOffset), m_mapSize))
    513 			isOk = false;
    514 
    515 		fillWithRandomBytes(refBuf.getPtr(m_mapOffset), m_mapSize, dataSeed&0xabcdef);
    516 		deMemcpy(ptr, refBuf.getPtr(m_mapOffset), m_mapSize);
    517 
    518 		glUnmapBuffer(m_bufferTarget);
    519 		GLU_CHECK_MSG("glUnmapBuffer");
    520 
    521 		// Compare final buffer.
    522 		if (!verifier.verify(buf, refBuf.getPtr(), 0, m_bufferSize, m_bufferTarget))
    523 			isOk = false;
    524 
    525 		deleteBuffer(buf);
    526 
    527 		m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS	: QP_TEST_RESULT_FAIL,
    528 								isOk ? "Pass"				: "Buffer verification failed");
    529 		return STOP;
    530 	}
    531 
    532 private:
    533 	deUint32		m_bufferTarget;
    534 	deUint32		m_usage;
    535 	int				m_bufferSize;
    536 	int				m_mapOffset;
    537 	int				m_mapSize;
    538 	VerifyType		m_verify;
    539 };
    540 
    541 BufferMapTests::BufferMapTests (Context& context)
    542 	: TestCaseGroup(context, "map", "Buffer map tests")
    543 {
    544 }
    545 
    546 BufferMapTests::~BufferMapTests (void)
    547 {
    548 }
    549 
    550 void BufferMapTests::init (void)
    551 {
    552 	static const deUint32 bufferTargets[] =
    553 	{
    554 		GL_ARRAY_BUFFER,
    555 		GL_COPY_READ_BUFFER,
    556 		GL_COPY_WRITE_BUFFER,
    557 		GL_ELEMENT_ARRAY_BUFFER,
    558 		GL_PIXEL_PACK_BUFFER,
    559 		GL_PIXEL_UNPACK_BUFFER,
    560 		GL_TRANSFORM_FEEDBACK_BUFFER,
    561 		GL_UNIFORM_BUFFER
    562 	};
    563 
    564 	static const deUint32 usageHints[] =
    565 	{
    566 		GL_STREAM_DRAW,
    567 		GL_STREAM_READ,
    568 		GL_STREAM_COPY,
    569 		GL_STATIC_DRAW,
    570 		GL_STATIC_READ,
    571 		GL_STATIC_COPY,
    572 		GL_DYNAMIC_DRAW,
    573 		GL_DYNAMIC_READ,
    574 		GL_DYNAMIC_COPY
    575 	};
    576 
    577 	static const struct
    578 	{
    579 		const char*		name;
    580 		WriteType		write;
    581 	} bufferDataSources[] =
    582 	{
    583 		{ "sub_data",		WRITE_BUFFER_SUB_DATA	},
    584 		{ "map_write",		WRITE_BUFFER_WRITE_MAP	}
    585 	};
    586 
    587 	static const struct
    588 	{
    589 		const char*		name;
    590 		VerifyType		verify;
    591 	} bufferUses[] =
    592 	{
    593 		{ "map_read",				VERIFY_BUFFER_READ_MAP	},
    594 		{ "render_as_vertex_array",	VERIFY_AS_VERTEX_ARRAY	},
    595 		{ "render_as_index_array",	VERIFY_AS_INDEX_ARRAY	}
    596 	};
    597 
    598 	// .read
    599 	{
    600 		tcu::TestCaseGroup* mapReadGroup = new tcu::TestCaseGroup(m_testCtx, "read", "Buffer read using glMapBufferRange()");
    601 		addChild(mapReadGroup);
    602 
    603 		// .[data src]
    604 		for (int srcNdx = 0; srcNdx < DE_LENGTH_OF_ARRAY(bufferDataSources); srcNdx++)
    605 		{
    606 			WriteType			write		= bufferDataSources[srcNdx].write;
    607 			tcu::TestCaseGroup* writeGroup	= new tcu::TestCaseGroup(m_testCtx, bufferDataSources[srcNdx].name, "");
    608 			mapReadGroup->addChild(writeGroup);
    609 
    610 			for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(bufferTargets); targetNdx++)
    611 			{
    612 				deUint32		target		= bufferTargets[targetNdx];
    613 				const deUint32	hint		= GL_STATIC_READ;
    614 				const int		size		= 1019;
    615 				const int		partialOffs	= 17;
    616 				const int		partialSize	= 501;
    617 
    618 				writeGroup->addChild(new BufferMapReadCase(m_context, (string(getBufferTargetName(target)) + "_full").c_str(),		"", target, hint, size, 0, size, write));
    619 				writeGroup->addChild(new BufferMapReadCase(m_context, (string(getBufferTargetName(target)) + "_partial").c_str(),	"", target, hint, size, partialOffs, partialSize, write));
    620 			}
    621 		}
    622 
    623 		// .usage_hints
    624 		{
    625 			tcu::TestCaseGroup* hintsGroup = new tcu::TestCaseGroup(m_testCtx, "usage_hints", "Different usage hints with glMapBufferRange()");
    626 			mapReadGroup->addChild(hintsGroup);
    627 
    628 			for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(bufferTargets); targetNdx++)
    629 			{
    630 				for (int hintNdx = 0; hintNdx < DE_LENGTH_OF_ARRAY(usageHints); hintNdx++)
    631 				{
    632 					deUint32		target		= bufferTargets[targetNdx];
    633 					deUint32		hint		= usageHints[hintNdx];
    634 					const int		size		= 1019;
    635 					string			name		= string(getBufferTargetName(target)) + "_" + getUsageHintName(hint);
    636 
    637 					hintsGroup->addChild(new BufferMapReadCase(m_context, name.c_str(), "", target, hint, size, 0, size, WRITE_BUFFER_SUB_DATA));
    638 				}
    639 			}
    640 		}
    641 	}
    642 
    643 	// .write
    644 	{
    645 		tcu::TestCaseGroup* mapWriteGroup = new tcu::TestCaseGroup(m_testCtx, "write", "Buffer write using glMapBufferRange()");
    646 		addChild(mapWriteGroup);
    647 
    648 		// .[verify type]
    649 		for (int useNdx = 0; useNdx < DE_LENGTH_OF_ARRAY(bufferUses); useNdx++)
    650 		{
    651 			VerifyType			verify		= bufferUses[useNdx].verify;
    652 			tcu::TestCaseGroup* useGroup	= new tcu::TestCaseGroup(m_testCtx, bufferUses[useNdx].name, "");
    653 			mapWriteGroup->addChild(useGroup);
    654 
    655 			for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(bufferTargets); targetNdx++)
    656 			{
    657 				deUint32		target		= bufferTargets[targetNdx];
    658 				deUint32		hint		= GL_STATIC_DRAW;
    659 				const int		size		= 1019;
    660 				const int		partialOffs	= 17;
    661 				const int		partialSize	= 501;
    662 				string			name		= string(getBufferTargetName(target)) + "_" + getUsageHintName(hint);
    663 
    664 				useGroup->addChild(new BufferMapWriteCase			(m_context, (string(getBufferTargetName(target)) + "_full").c_str(),	"", target, hint, size, verify));
    665 				useGroup->addChild(new BufferPartialMapWriteCase	(m_context, (string(getBufferTargetName(target)) + "_partial").c_str(),	"", target, hint, size, partialOffs, partialSize, verify));
    666 			}
    667 		}
    668 
    669 		// .usage_hints
    670 		{
    671 			tcu::TestCaseGroup* hintsGroup = new tcu::TestCaseGroup(m_testCtx, "usage_hints", "Usage hints");
    672 			mapWriteGroup->addChild(hintsGroup);
    673 
    674 			for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(bufferTargets); targetNdx++)
    675 			{
    676 				for (int hintNdx = 0; hintNdx < DE_LENGTH_OF_ARRAY(usageHints); hintNdx++)
    677 				{
    678 					deUint32		target		= bufferTargets[targetNdx];
    679 					deUint32		hint		= usageHints[hintNdx];
    680 					const int		size		= 1019;
    681 					string			name		= string(getBufferTargetName(target)) + "_" + getUsageHintName(hint);
    682 
    683 					hintsGroup->addChild(new BufferMapWriteCase(m_context, name.c_str(), "", target, hint, size, VERIFY_AS_VERTEX_ARRAY));
    684 				}
    685 			}
    686 		}
    687 
    688 		// .invalidate
    689 		{
    690 			tcu::TestCaseGroup* invalidateGroup = new tcu::TestCaseGroup(m_testCtx, "invalidate", "Buffer invalidate");
    691 			mapWriteGroup->addChild(invalidateGroup);
    692 
    693 			for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(bufferTargets); targetNdx++)
    694 			{
    695 				deUint32		target		= bufferTargets[targetNdx];
    696 				deUint32		hint		= GL_STATIC_DRAW;
    697 
    698 				invalidateGroup->addChild(new BufferMapInvalidateCase(m_context, (string(getBufferTargetName(target)) + "_write_all").c_str(),		"", target, hint, false,	VERIFY_AS_VERTEX_ARRAY));
    699 				invalidateGroup->addChild(new BufferMapInvalidateCase(m_context, (string(getBufferTargetName(target)) + "_write_partial").c_str(),	"", target, hint, true,		VERIFY_AS_VERTEX_ARRAY));
    700 			}
    701 		}
    702 
    703 		// .partial_invalidate
    704 		{
    705 			tcu::TestCaseGroup* invalidateGroup = new tcu::TestCaseGroup(m_testCtx, "partial_invalidate", "Partial invalidate");
    706 			mapWriteGroup->addChild(invalidateGroup);
    707 
    708 			for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(bufferTargets); targetNdx++)
    709 			{
    710 				deUint32		target		= bufferTargets[targetNdx];
    711 				deUint32		hint		= GL_STATIC_DRAW;
    712 
    713 				invalidateGroup->addChild(new BufferMapPartialInvalidateCase(m_context, (string(getBufferTargetName(target)) + "_write_all").c_str(),		"", target, hint, false,	VERIFY_AS_VERTEX_ARRAY));
    714 				invalidateGroup->addChild(new BufferMapPartialInvalidateCase(m_context, (string(getBufferTargetName(target)) + "_write_partial").c_str(),	"", target, hint, true,		VERIFY_AS_VERTEX_ARRAY));
    715 			}
    716 		}
    717 
    718 		// .explicit_flush
    719 		{
    720 			tcu::TestCaseGroup* flushGroup = new tcu::TestCaseGroup(m_testCtx, "explicit_flush", "Explicit flush");
    721 			mapWriteGroup->addChild(flushGroup);
    722 
    723 			for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(bufferTargets); targetNdx++)
    724 			{
    725 				deUint32		target		= bufferTargets[targetNdx];
    726 				deUint32		hint		= GL_STATIC_DRAW;
    727 
    728 				flushGroup->addChild(new BufferMapExplicitFlushCase(m_context, (string(getBufferTargetName(target)) + "_all").c_str(),		"", target, hint, false,	VERIFY_AS_VERTEX_ARRAY));
    729 				flushGroup->addChild(new BufferMapExplicitFlushCase(m_context, (string(getBufferTargetName(target)) + "_partial").c_str(),	"", target, hint, true,		VERIFY_AS_VERTEX_ARRAY));
    730 			}
    731 		}
    732 
    733 		// .unsynchronized
    734 		{
    735 			tcu::TestCaseGroup* unsyncGroup = new tcu::TestCaseGroup(m_testCtx, "unsynchronized", "Unsynchronized map");
    736 			mapWriteGroup->addChild(unsyncGroup);
    737 
    738 			for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(bufferTargets); targetNdx++)
    739 			{
    740 				deUint32		target		= bufferTargets[targetNdx];
    741 				deUint32		hint		= GL_STATIC_DRAW;
    742 
    743 				unsyncGroup->addChild(new BufferMapUnsyncWriteCase(m_context, getBufferTargetName(target),	"", target, hint));
    744 			}
    745 		}
    746 	}
    747 
    748 	// .read_write
    749 	{
    750 		tcu::TestCaseGroup* mapReadWriteGroup = new tcu::TestCaseGroup(m_testCtx, "read_write", "Buffer read and write using glMapBufferRange()");
    751 		addChild(mapReadWriteGroup);
    752 
    753 		// .[verify type]
    754 		for (int useNdx = 0; useNdx < DE_LENGTH_OF_ARRAY(bufferUses); useNdx++)
    755 		{
    756 			VerifyType			verify		= bufferUses[useNdx].verify;
    757 			tcu::TestCaseGroup* useGroup	= new tcu::TestCaseGroup(m_testCtx, bufferUses[useNdx].name, "");
    758 			mapReadWriteGroup->addChild(useGroup);
    759 
    760 			for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(bufferTargets); targetNdx++)
    761 			{
    762 				deUint32		target		= bufferTargets[targetNdx];
    763 				deUint32		hint		= GL_STATIC_DRAW;
    764 				const int		size		= 1019;
    765 				const int		partialOffs	= 17;
    766 				const int		partialSize	= 501;
    767 				string			name		= string(getBufferTargetName(target)) + "_" + getUsageHintName(hint);
    768 
    769 				useGroup->addChild(new BufferMapReadWriteCase(m_context, (string(getBufferTargetName(target)) + "_full").c_str(),		"", target, hint, size, 0, size, verify));
    770 				useGroup->addChild(new BufferMapReadWriteCase(m_context, (string(getBufferTargetName(target)) + "_partial").c_str(),	"", target, hint, size, partialOffs, partialSize, verify));
    771 			}
    772 		}
    773 
    774 		// .usage_hints
    775 		{
    776 			tcu::TestCaseGroup* hintsGroup = new tcu::TestCaseGroup(m_testCtx, "usage_hints", "Usage hints");
    777 			mapReadWriteGroup->addChild(hintsGroup);
    778 
    779 			for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(bufferTargets); targetNdx++)
    780 			{
    781 				for (int hintNdx = 0; hintNdx < DE_LENGTH_OF_ARRAY(usageHints); hintNdx++)
    782 				{
    783 					deUint32		target		= bufferTargets[targetNdx];
    784 					deUint32		hint		= usageHints[hintNdx];
    785 					const int		size		= 1019;
    786 					string			name		= string(getBufferTargetName(target)) + "_" + getUsageHintName(hint);
    787 
    788 					hintsGroup->addChild(new BufferMapReadWriteCase(m_context, name.c_str(), "", target, hint, size, 0, size, VERIFY_AS_VERTEX_ARRAY));
    789 				}
    790 			}
    791 		}
    792 	}
    793 }
    794 
    795 } // Functional
    796 } // gles3
    797 } // deqp
    798