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