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 34using std::vector; 35using std::string; 36using tcu::TestLog; 37 38namespace deqp 39{ 40namespace gles3 41{ 42namespace Functional 43{ 44 45using namespace gls::BufferTestUtil; 46 47class BasicBufferCopyCase : public BufferCase 48{ 49public: 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 129private: 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 147class SingleBufferCopyCase : public BufferCase 148{ 149public: 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 222private: 223 deUint32 m_srcTarget; 224 deUint32 m_dstTarget; 225 deUint32 m_hint; 226 227 VerifyType m_verifyType; 228}; 229 230BufferCopyTests::BufferCopyTests (Context& context) 231 : TestCaseGroup(context, "copy", "Buffer copy tests") 232{ 233} 234 235BufferCopyTests::~BufferCopyTests (void) 236{ 237} 238 239void 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