xref: /aosp_15_r20/external/deqp/modules/gles31/functional/es31fBasicComputeShaderTests.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
1*35238bceSAndroid Build Coastguard Worker /*-------------------------------------------------------------------------
2*35238bceSAndroid Build Coastguard Worker  * drawElements Quality Program OpenGL ES 3.1 Module
3*35238bceSAndroid Build Coastguard Worker  * -------------------------------------------------
4*35238bceSAndroid Build Coastguard Worker  *
5*35238bceSAndroid Build Coastguard Worker  * Copyright 2014 The Android Open Source Project
6*35238bceSAndroid Build Coastguard Worker  *
7*35238bceSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
8*35238bceSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
9*35238bceSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
10*35238bceSAndroid Build Coastguard Worker  *
11*35238bceSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
12*35238bceSAndroid Build Coastguard Worker  *
13*35238bceSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
14*35238bceSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
15*35238bceSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16*35238bceSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
17*35238bceSAndroid Build Coastguard Worker  * limitations under the License.
18*35238bceSAndroid Build Coastguard Worker  *
19*35238bceSAndroid Build Coastguard Worker  *//*!
20*35238bceSAndroid Build Coastguard Worker  * \file
21*35238bceSAndroid Build Coastguard Worker  * \brief Basic Compute Shader Tests.
22*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
23*35238bceSAndroid Build Coastguard Worker 
24*35238bceSAndroid Build Coastguard Worker #include "es31fBasicComputeShaderTests.hpp"
25*35238bceSAndroid Build Coastguard Worker #include "gluShaderProgram.hpp"
26*35238bceSAndroid Build Coastguard Worker #include "gluObjectWrapper.hpp"
27*35238bceSAndroid Build Coastguard Worker #include "gluRenderContext.hpp"
28*35238bceSAndroid Build Coastguard Worker #include "gluProgramInterfaceQuery.hpp"
29*35238bceSAndroid Build Coastguard Worker #include "gluContextInfo.hpp"
30*35238bceSAndroid Build Coastguard Worker #include "glwFunctions.hpp"
31*35238bceSAndroid Build Coastguard Worker #include "glwEnums.hpp"
32*35238bceSAndroid Build Coastguard Worker #include "tcuTestLog.hpp"
33*35238bceSAndroid Build Coastguard Worker #include "deRandom.hpp"
34*35238bceSAndroid Build Coastguard Worker #include "deStringUtil.hpp"
35*35238bceSAndroid Build Coastguard Worker #include "deMemory.h"
36*35238bceSAndroid Build Coastguard Worker 
37*35238bceSAndroid Build Coastguard Worker namespace deqp
38*35238bceSAndroid Build Coastguard Worker {
39*35238bceSAndroid Build Coastguard Worker namespace gles31
40*35238bceSAndroid Build Coastguard Worker {
41*35238bceSAndroid Build Coastguard Worker namespace Functional
42*35238bceSAndroid Build Coastguard Worker {
43*35238bceSAndroid Build Coastguard Worker 
44*35238bceSAndroid Build Coastguard Worker using std::string;
45*35238bceSAndroid Build Coastguard Worker using std::vector;
46*35238bceSAndroid Build Coastguard Worker using tcu::TestLog;
47*35238bceSAndroid Build Coastguard Worker using namespace glu;
48*35238bceSAndroid Build Coastguard Worker 
49*35238bceSAndroid Build Coastguard Worker //! Utility for mapping buffers.
50*35238bceSAndroid Build Coastguard Worker class BufferMemMap
51*35238bceSAndroid Build Coastguard Worker {
52*35238bceSAndroid Build Coastguard Worker public:
BufferMemMap(const glw::Functions & gl,uint32_t target,int offset,int size,uint32_t access)53*35238bceSAndroid Build Coastguard Worker     BufferMemMap(const glw::Functions &gl, uint32_t target, int offset, int size, uint32_t access)
54*35238bceSAndroid Build Coastguard Worker         : m_gl(gl)
55*35238bceSAndroid Build Coastguard Worker         , m_target(target)
56*35238bceSAndroid Build Coastguard Worker         , m_ptr(DE_NULL)
57*35238bceSAndroid Build Coastguard Worker     {
58*35238bceSAndroid Build Coastguard Worker         m_ptr = gl.mapBufferRange(target, offset, size, access);
59*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBufferRange()");
60*35238bceSAndroid Build Coastguard Worker         TCU_CHECK(m_ptr);
61*35238bceSAndroid Build Coastguard Worker     }
62*35238bceSAndroid Build Coastguard Worker 
~BufferMemMap(void)63*35238bceSAndroid Build Coastguard Worker     ~BufferMemMap(void)
64*35238bceSAndroid Build Coastguard Worker     {
65*35238bceSAndroid Build Coastguard Worker         m_gl.unmapBuffer(m_target);
66*35238bceSAndroid Build Coastguard Worker     }
67*35238bceSAndroid Build Coastguard Worker 
getPtr(void) const68*35238bceSAndroid Build Coastguard Worker     void *getPtr(void) const
69*35238bceSAndroid Build Coastguard Worker     {
70*35238bceSAndroid Build Coastguard Worker         return m_ptr;
71*35238bceSAndroid Build Coastguard Worker     }
operator *(void) const72*35238bceSAndroid Build Coastguard Worker     void *operator*(void) const
73*35238bceSAndroid Build Coastguard Worker     {
74*35238bceSAndroid Build Coastguard Worker         return m_ptr;
75*35238bceSAndroid Build Coastguard Worker     }
76*35238bceSAndroid Build Coastguard Worker 
77*35238bceSAndroid Build Coastguard Worker private:
78*35238bceSAndroid Build Coastguard Worker     BufferMemMap(const BufferMemMap &other);
79*35238bceSAndroid Build Coastguard Worker     BufferMemMap &operator=(const BufferMemMap &other);
80*35238bceSAndroid Build Coastguard Worker 
81*35238bceSAndroid Build Coastguard Worker     const glw::Functions &m_gl;
82*35238bceSAndroid Build Coastguard Worker     const uint32_t m_target;
83*35238bceSAndroid Build Coastguard Worker     void *m_ptr;
84*35238bceSAndroid Build Coastguard Worker };
85*35238bceSAndroid Build Coastguard Worker 
86*35238bceSAndroid Build Coastguard Worker namespace
87*35238bceSAndroid Build Coastguard Worker {
88*35238bceSAndroid Build Coastguard Worker 
89*35238bceSAndroid Build Coastguard Worker class EmptyComputeShaderCase : public TestCase
90*35238bceSAndroid Build Coastguard Worker {
91*35238bceSAndroid Build Coastguard Worker public:
EmptyComputeShaderCase(Context & context)92*35238bceSAndroid Build Coastguard Worker     EmptyComputeShaderCase(Context &context) : TestCase(context, "empty", "Empty shader")
93*35238bceSAndroid Build Coastguard Worker     {
94*35238bceSAndroid Build Coastguard Worker     }
95*35238bceSAndroid Build Coastguard Worker 
iterate(void)96*35238bceSAndroid Build Coastguard Worker     IterateResult iterate(void)
97*35238bceSAndroid Build Coastguard Worker     {
98*35238bceSAndroid Build Coastguard Worker         const GLSLVersion glslVersion = glu::getContextTypeGLSLVersion(m_context.getRenderContext().getType());
99*35238bceSAndroid Build Coastguard Worker         std::ostringstream src;
100*35238bceSAndroid Build Coastguard Worker 
101*35238bceSAndroid Build Coastguard Worker         src << getGLSLVersionDeclaration(glslVersion) << "\n"
102*35238bceSAndroid Build Coastguard Worker             << "layout (local_size_x = 1) in;\n"
103*35238bceSAndroid Build Coastguard Worker                "void main (void) {}\n";
104*35238bceSAndroid Build Coastguard Worker 
105*35238bceSAndroid Build Coastguard Worker         const ShaderProgram program(m_context.getRenderContext(), ProgramSources()
106*35238bceSAndroid Build Coastguard Worker                                                                       << ShaderSource(SHADERTYPE_COMPUTE, src.str()));
107*35238bceSAndroid Build Coastguard Worker 
108*35238bceSAndroid Build Coastguard Worker         const glw::Functions &gl = m_context.getRenderContext().getFunctions();
109*35238bceSAndroid Build Coastguard Worker 
110*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << program;
111*35238bceSAndroid Build Coastguard Worker         if (!program.isOk())
112*35238bceSAndroid Build Coastguard Worker             TCU_FAIL("Compile failed");
113*35238bceSAndroid Build Coastguard Worker 
114*35238bceSAndroid Build Coastguard Worker         gl.useProgram(program.getProgram());
115*35238bceSAndroid Build Coastguard Worker         gl.dispatchCompute(1, 1, 1);
116*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(gl.getError(), "glDispatchCompute()");
117*35238bceSAndroid Build Coastguard Worker 
118*35238bceSAndroid Build Coastguard Worker         m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
119*35238bceSAndroid Build Coastguard Worker         return STOP;
120*35238bceSAndroid Build Coastguard Worker     }
121*35238bceSAndroid Build Coastguard Worker };
122*35238bceSAndroid Build Coastguard Worker 
123*35238bceSAndroid Build Coastguard Worker class UBOToSSBOInvertCase : public TestCase
124*35238bceSAndroid Build Coastguard Worker {
125*35238bceSAndroid Build Coastguard Worker public:
UBOToSSBOInvertCase(Context & context,const char * name,const char * description,int numValues,const tcu::IVec3 & localSize,const tcu::IVec3 & workSize)126*35238bceSAndroid Build Coastguard Worker     UBOToSSBOInvertCase(Context &context, const char *name, const char *description, int numValues,
127*35238bceSAndroid Build Coastguard Worker                         const tcu::IVec3 &localSize, const tcu::IVec3 &workSize)
128*35238bceSAndroid Build Coastguard Worker         : TestCase(context, name, description)
129*35238bceSAndroid Build Coastguard Worker         , m_numValues(numValues)
130*35238bceSAndroid Build Coastguard Worker         , m_localSize(localSize)
131*35238bceSAndroid Build Coastguard Worker         , m_workSize(workSize)
132*35238bceSAndroid Build Coastguard Worker     {
133*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(m_numValues % (m_workSize[0] * m_workSize[1] * m_workSize[2] * m_localSize[0] * m_localSize[1] *
134*35238bceSAndroid Build Coastguard Worker                                  m_localSize[2]) ==
135*35238bceSAndroid Build Coastguard Worker                   0);
136*35238bceSAndroid Build Coastguard Worker     }
137*35238bceSAndroid Build Coastguard Worker 
iterate(void)138*35238bceSAndroid Build Coastguard Worker     IterateResult iterate(void)
139*35238bceSAndroid Build Coastguard Worker     {
140*35238bceSAndroid Build Coastguard Worker         const GLSLVersion glslVersion = glu::getContextTypeGLSLVersion(m_context.getRenderContext().getType());
141*35238bceSAndroid Build Coastguard Worker         std::ostringstream src;
142*35238bceSAndroid Build Coastguard Worker 
143*35238bceSAndroid Build Coastguard Worker         src << getGLSLVersionDeclaration(glslVersion) << "\n"
144*35238bceSAndroid Build Coastguard Worker             << "layout (local_size_x = " << m_localSize[0] << ", local_size_y = " << m_localSize[1]
145*35238bceSAndroid Build Coastguard Worker             << ", local_size_z = " << m_localSize[2] << ") in;\n"
146*35238bceSAndroid Build Coastguard Worker             << "uniform Input {\n"
147*35238bceSAndroid Build Coastguard Worker             << "    uint values[" << m_numValues << "];\n"
148*35238bceSAndroid Build Coastguard Worker             << "} ub_in;\n"
149*35238bceSAndroid Build Coastguard Worker             << "layout(binding = 1) buffer Output {\n"
150*35238bceSAndroid Build Coastguard Worker             << "    uint values[" << m_numValues << "];\n"
151*35238bceSAndroid Build Coastguard Worker             << "} sb_out;\n"
152*35238bceSAndroid Build Coastguard Worker             << "void main (void) {\n"
153*35238bceSAndroid Build Coastguard Worker             << "    uvec3 size           = gl_NumWorkGroups * gl_WorkGroupSize;\n"
154*35238bceSAndroid Build Coastguard Worker             << "    uint numValuesPerInv = uint(ub_in.values.length()) / (size.x*size.y*size.z);\n"
155*35238bceSAndroid Build Coastguard Worker             << "    uint groupNdx        = size.x*size.y*gl_GlobalInvocationID.z + size.x*gl_GlobalInvocationID.y + "
156*35238bceSAndroid Build Coastguard Worker                "gl_GlobalInvocationID.x;\n"
157*35238bceSAndroid Build Coastguard Worker             << "    uint offset          = numValuesPerInv*groupNdx;\n"
158*35238bceSAndroid Build Coastguard Worker             << "\n"
159*35238bceSAndroid Build Coastguard Worker             << "    for (uint ndx = 0u; ndx < numValuesPerInv; ndx++)\n"
160*35238bceSAndroid Build Coastguard Worker             << "        sb_out.values[offset + ndx] = ~ub_in.values[offset + ndx];\n"
161*35238bceSAndroid Build Coastguard Worker             << "}\n";
162*35238bceSAndroid Build Coastguard Worker 
163*35238bceSAndroid Build Coastguard Worker         const glw::Functions &gl = m_context.getRenderContext().getFunctions();
164*35238bceSAndroid Build Coastguard Worker         const ShaderProgram program(m_context.getRenderContext(), ProgramSources()
165*35238bceSAndroid Build Coastguard Worker                                                                       << ShaderSource(SHADERTYPE_COMPUTE, src.str()));
166*35238bceSAndroid Build Coastguard Worker         const Buffer inputBuffer(m_context.getRenderContext());
167*35238bceSAndroid Build Coastguard Worker         const Buffer outputBuffer(m_context.getRenderContext());
168*35238bceSAndroid Build Coastguard Worker         std::vector<uint32_t> inputValues(m_numValues);
169*35238bceSAndroid Build Coastguard Worker 
170*35238bceSAndroid Build Coastguard Worker         // Compute input values.
171*35238bceSAndroid Build Coastguard Worker         {
172*35238bceSAndroid Build Coastguard Worker             de::Random rnd(0x111223f);
173*35238bceSAndroid Build Coastguard Worker             for (int ndx = 0; ndx < (int)inputValues.size(); ndx++)
174*35238bceSAndroid Build Coastguard Worker                 inputValues[ndx] = rnd.getUint32();
175*35238bceSAndroid Build Coastguard Worker         }
176*35238bceSAndroid Build Coastguard Worker 
177*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << program;
178*35238bceSAndroid Build Coastguard Worker         if (!program.isOk())
179*35238bceSAndroid Build Coastguard Worker             TCU_FAIL("Compile failed");
180*35238bceSAndroid Build Coastguard Worker 
181*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << TestLog::Message << "Work groups: " << m_workSize << TestLog::EndMessage;
182*35238bceSAndroid Build Coastguard Worker 
183*35238bceSAndroid Build Coastguard Worker         gl.useProgram(program.getProgram());
184*35238bceSAndroid Build Coastguard Worker 
185*35238bceSAndroid Build Coastguard Worker         // Input buffer setup
186*35238bceSAndroid Build Coastguard Worker         {
187*35238bceSAndroid Build Coastguard Worker             const uint32_t blockIndex = gl.getProgramResourceIndex(program.getProgram(), GL_UNIFORM_BLOCK, "Input");
188*35238bceSAndroid Build Coastguard Worker             const InterfaceBlockInfo blockInfo =
189*35238bceSAndroid Build Coastguard Worker                 getProgramInterfaceBlockInfo(gl, program.getProgram(), GL_UNIFORM_BLOCK, blockIndex);
190*35238bceSAndroid Build Coastguard Worker             const uint32_t valueIndex = gl.getProgramResourceIndex(program.getProgram(), GL_UNIFORM, "Input.values");
191*35238bceSAndroid Build Coastguard Worker             const InterfaceVariableInfo valueInfo =
192*35238bceSAndroid Build Coastguard Worker                 getProgramInterfaceVariableInfo(gl, program.getProgram(), GL_UNIFORM, valueIndex);
193*35238bceSAndroid Build Coastguard Worker 
194*35238bceSAndroid Build Coastguard Worker             gl.bindBuffer(GL_UNIFORM_BUFFER, *inputBuffer);
195*35238bceSAndroid Build Coastguard Worker             gl.bufferData(GL_UNIFORM_BUFFER, (glw::GLsizeiptr)blockInfo.dataSize, DE_NULL, GL_STATIC_DRAW);
196*35238bceSAndroid Build Coastguard Worker 
197*35238bceSAndroid Build Coastguard Worker             {
198*35238bceSAndroid Build Coastguard Worker                 const BufferMemMap bufMap(gl, GL_UNIFORM_BUFFER, 0, (int)blockInfo.dataSize, GL_MAP_WRITE_BIT);
199*35238bceSAndroid Build Coastguard Worker 
200*35238bceSAndroid Build Coastguard Worker                 for (uint32_t ndx = 0; ndx < de::min(valueInfo.arraySize, (uint32_t)inputValues.size()); ndx++)
201*35238bceSAndroid Build Coastguard Worker                     *(uint32_t *)((uint8_t *)bufMap.getPtr() + valueInfo.offset + ndx * valueInfo.arrayStride) =
202*35238bceSAndroid Build Coastguard Worker                         inputValues[ndx];
203*35238bceSAndroid Build Coastguard Worker             }
204*35238bceSAndroid Build Coastguard Worker 
205*35238bceSAndroid Build Coastguard Worker             gl.uniformBlockBinding(program.getProgram(), blockIndex, 0);
206*35238bceSAndroid Build Coastguard Worker             gl.bindBufferBase(GL_UNIFORM_BUFFER, 0, *inputBuffer);
207*35238bceSAndroid Build Coastguard Worker             GLU_EXPECT_NO_ERROR(gl.getError(), "Input buffer setup failed");
208*35238bceSAndroid Build Coastguard Worker         }
209*35238bceSAndroid Build Coastguard Worker 
210*35238bceSAndroid Build Coastguard Worker         // Output buffer setup
211*35238bceSAndroid Build Coastguard Worker         {
212*35238bceSAndroid Build Coastguard Worker             const uint32_t blockIndex =
213*35238bceSAndroid Build Coastguard Worker                 gl.getProgramResourceIndex(program.getProgram(), GL_SHADER_STORAGE_BLOCK, "Output");
214*35238bceSAndroid Build Coastguard Worker             const int blockSize = getProgramResourceInt(gl, program.getProgram(), GL_SHADER_STORAGE_BLOCK, blockIndex,
215*35238bceSAndroid Build Coastguard Worker                                                         GL_BUFFER_DATA_SIZE);
216*35238bceSAndroid Build Coastguard Worker 
217*35238bceSAndroid Build Coastguard Worker             gl.bindBuffer(GL_SHADER_STORAGE_BUFFER, *outputBuffer);
218*35238bceSAndroid Build Coastguard Worker             gl.bufferData(GL_SHADER_STORAGE_BUFFER, blockSize, DE_NULL, GL_STREAM_READ);
219*35238bceSAndroid Build Coastguard Worker             gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, *outputBuffer);
220*35238bceSAndroid Build Coastguard Worker             GLU_EXPECT_NO_ERROR(gl.getError(), "Output buffer setup failed");
221*35238bceSAndroid Build Coastguard Worker         }
222*35238bceSAndroid Build Coastguard Worker 
223*35238bceSAndroid Build Coastguard Worker         // Dispatch compute workload
224*35238bceSAndroid Build Coastguard Worker         gl.dispatchCompute(m_workSize[0], m_workSize[1], m_workSize[2]);
225*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(gl.getError(), "glDispatchCompute()");
226*35238bceSAndroid Build Coastguard Worker 
227*35238bceSAndroid Build Coastguard Worker         // Read back and compare
228*35238bceSAndroid Build Coastguard Worker         {
229*35238bceSAndroid Build Coastguard Worker             const uint32_t blockIndex =
230*35238bceSAndroid Build Coastguard Worker                 gl.getProgramResourceIndex(program.getProgram(), GL_SHADER_STORAGE_BLOCK, "Output");
231*35238bceSAndroid Build Coastguard Worker             const int blockSize = getProgramResourceInt(gl, program.getProgram(), GL_SHADER_STORAGE_BLOCK, blockIndex,
232*35238bceSAndroid Build Coastguard Worker                                                         GL_BUFFER_DATA_SIZE);
233*35238bceSAndroid Build Coastguard Worker             const uint32_t valueIndex =
234*35238bceSAndroid Build Coastguard Worker                 gl.getProgramResourceIndex(program.getProgram(), GL_BUFFER_VARIABLE, "Output.values");
235*35238bceSAndroid Build Coastguard Worker             const InterfaceVariableInfo valueInfo =
236*35238bceSAndroid Build Coastguard Worker                 getProgramInterfaceVariableInfo(gl, program.getProgram(), GL_BUFFER_VARIABLE, valueIndex);
237*35238bceSAndroid Build Coastguard Worker             const BufferMemMap bufMap(gl, GL_SHADER_STORAGE_BUFFER, 0, blockSize, GL_MAP_READ_BIT);
238*35238bceSAndroid Build Coastguard Worker 
239*35238bceSAndroid Build Coastguard Worker             TCU_CHECK(valueInfo.arraySize == (uint32_t)inputValues.size());
240*35238bceSAndroid Build Coastguard Worker             for (uint32_t ndx = 0; ndx < valueInfo.arraySize; ndx++)
241*35238bceSAndroid Build Coastguard Worker             {
242*35238bceSAndroid Build Coastguard Worker                 const uint32_t res = *((const uint32_t *)((const uint8_t *)bufMap.getPtr() + valueInfo.offset +
243*35238bceSAndroid Build Coastguard Worker                                                           valueInfo.arrayStride * ndx));
244*35238bceSAndroid Build Coastguard Worker                 const uint32_t ref = ~inputValues[ndx];
245*35238bceSAndroid Build Coastguard Worker 
246*35238bceSAndroid Build Coastguard Worker                 if (res != ref)
247*35238bceSAndroid Build Coastguard Worker                     throw tcu::TestError(string("Comparison failed for Output.values[") + de::toString(ndx) + "]");
248*35238bceSAndroid Build Coastguard Worker             }
249*35238bceSAndroid Build Coastguard Worker         }
250*35238bceSAndroid Build Coastguard Worker 
251*35238bceSAndroid Build Coastguard Worker         m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
252*35238bceSAndroid Build Coastguard Worker         return STOP;
253*35238bceSAndroid Build Coastguard Worker     }
254*35238bceSAndroid Build Coastguard Worker 
255*35238bceSAndroid Build Coastguard Worker private:
256*35238bceSAndroid Build Coastguard Worker     const int m_numValues;
257*35238bceSAndroid Build Coastguard Worker     const tcu::IVec3 m_localSize;
258*35238bceSAndroid Build Coastguard Worker     const tcu::IVec3 m_workSize;
259*35238bceSAndroid Build Coastguard Worker };
260*35238bceSAndroid Build Coastguard Worker 
261*35238bceSAndroid Build Coastguard Worker class CopyInvertSSBOCase : public TestCase
262*35238bceSAndroid Build Coastguard Worker {
263*35238bceSAndroid Build Coastguard Worker public:
CopyInvertSSBOCase(Context & context,const char * name,const char * description,int numValues,const tcu::IVec3 & localSize,const tcu::IVec3 & workSize)264*35238bceSAndroid Build Coastguard Worker     CopyInvertSSBOCase(Context &context, const char *name, const char *description, int numValues,
265*35238bceSAndroid Build Coastguard Worker                        const tcu::IVec3 &localSize, const tcu::IVec3 &workSize)
266*35238bceSAndroid Build Coastguard Worker         : TestCase(context, name, description)
267*35238bceSAndroid Build Coastguard Worker         , m_numValues(numValues)
268*35238bceSAndroid Build Coastguard Worker         , m_localSize(localSize)
269*35238bceSAndroid Build Coastguard Worker         , m_workSize(workSize)
270*35238bceSAndroid Build Coastguard Worker     {
271*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(m_numValues % (m_workSize[0] * m_workSize[1] * m_workSize[2] * m_localSize[0] * m_localSize[1] *
272*35238bceSAndroid Build Coastguard Worker                                  m_localSize[2]) ==
273*35238bceSAndroid Build Coastguard Worker                   0);
274*35238bceSAndroid Build Coastguard Worker     }
275*35238bceSAndroid Build Coastguard Worker 
iterate(void)276*35238bceSAndroid Build Coastguard Worker     IterateResult iterate(void)
277*35238bceSAndroid Build Coastguard Worker     {
278*35238bceSAndroid Build Coastguard Worker         const GLSLVersion glslVersion = glu::getContextTypeGLSLVersion(m_context.getRenderContext().getType());
279*35238bceSAndroid Build Coastguard Worker         std::ostringstream src;
280*35238bceSAndroid Build Coastguard Worker 
281*35238bceSAndroid Build Coastguard Worker         src << getGLSLVersionDeclaration(glslVersion) << "\n"
282*35238bceSAndroid Build Coastguard Worker             << "layout (local_size_x = " << m_localSize[0] << ", local_size_y = " << m_localSize[1]
283*35238bceSAndroid Build Coastguard Worker             << ", local_size_z = " << m_localSize[2] << ") in;\n"
284*35238bceSAndroid Build Coastguard Worker             << "layout(binding = 0) buffer Input {\n"
285*35238bceSAndroid Build Coastguard Worker             << "    uint values[" << m_numValues << "];\n"
286*35238bceSAndroid Build Coastguard Worker             << "} sb_in;\n"
287*35238bceSAndroid Build Coastguard Worker             << "layout (binding = 1) buffer Output {\n"
288*35238bceSAndroid Build Coastguard Worker             << "    uint values[" << m_numValues << "];\n"
289*35238bceSAndroid Build Coastguard Worker             << "} sb_out;\n"
290*35238bceSAndroid Build Coastguard Worker             << "void main (void) {\n"
291*35238bceSAndroid Build Coastguard Worker             << "    uvec3 size           = gl_NumWorkGroups * gl_WorkGroupSize;\n"
292*35238bceSAndroid Build Coastguard Worker             << "    uint numValuesPerInv = uint(sb_in.values.length()) / (size.x*size.y*size.z);\n"
293*35238bceSAndroid Build Coastguard Worker             << "    uint groupNdx        = size.x*size.y*gl_GlobalInvocationID.z + size.x*gl_GlobalInvocationID.y + "
294*35238bceSAndroid Build Coastguard Worker                "gl_GlobalInvocationID.x;\n"
295*35238bceSAndroid Build Coastguard Worker             << "    uint offset          = numValuesPerInv*groupNdx;\n"
296*35238bceSAndroid Build Coastguard Worker             << "\n"
297*35238bceSAndroid Build Coastguard Worker             << "    for (uint ndx = 0u; ndx < numValuesPerInv; ndx++)\n"
298*35238bceSAndroid Build Coastguard Worker             << "        sb_out.values[offset + ndx] = ~sb_in.values[offset + ndx];\n"
299*35238bceSAndroid Build Coastguard Worker             << "}\n";
300*35238bceSAndroid Build Coastguard Worker 
301*35238bceSAndroid Build Coastguard Worker         const glw::Functions &gl = m_context.getRenderContext().getFunctions();
302*35238bceSAndroid Build Coastguard Worker         const ShaderProgram program(m_context.getRenderContext(), ProgramSources()
303*35238bceSAndroid Build Coastguard Worker                                                                       << ShaderSource(SHADERTYPE_COMPUTE, src.str()));
304*35238bceSAndroid Build Coastguard Worker         const Buffer inputBuffer(m_context.getRenderContext());
305*35238bceSAndroid Build Coastguard Worker         const Buffer outputBuffer(m_context.getRenderContext());
306*35238bceSAndroid Build Coastguard Worker         std::vector<uint32_t> inputValues(m_numValues);
307*35238bceSAndroid Build Coastguard Worker 
308*35238bceSAndroid Build Coastguard Worker         // Compute input values.
309*35238bceSAndroid Build Coastguard Worker         {
310*35238bceSAndroid Build Coastguard Worker             de::Random rnd(0x124fef);
311*35238bceSAndroid Build Coastguard Worker             for (int ndx = 0; ndx < (int)inputValues.size(); ndx++)
312*35238bceSAndroid Build Coastguard Worker                 inputValues[ndx] = rnd.getUint32();
313*35238bceSAndroid Build Coastguard Worker         }
314*35238bceSAndroid Build Coastguard Worker 
315*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << program;
316*35238bceSAndroid Build Coastguard Worker         if (!program.isOk())
317*35238bceSAndroid Build Coastguard Worker             TCU_FAIL("Compile failed");
318*35238bceSAndroid Build Coastguard Worker 
319*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << TestLog::Message << "Work groups: " << m_workSize << TestLog::EndMessage;
320*35238bceSAndroid Build Coastguard Worker 
321*35238bceSAndroid Build Coastguard Worker         gl.useProgram(program.getProgram());
322*35238bceSAndroid Build Coastguard Worker 
323*35238bceSAndroid Build Coastguard Worker         // Input buffer setup
324*35238bceSAndroid Build Coastguard Worker         {
325*35238bceSAndroid Build Coastguard Worker             const uint32_t blockIndex =
326*35238bceSAndroid Build Coastguard Worker                 gl.getProgramResourceIndex(program.getProgram(), GL_SHADER_STORAGE_BLOCK, "Input");
327*35238bceSAndroid Build Coastguard Worker             const InterfaceBlockInfo blockInfo =
328*35238bceSAndroid Build Coastguard Worker                 getProgramInterfaceBlockInfo(gl, program.getProgram(), GL_SHADER_STORAGE_BLOCK, blockIndex);
329*35238bceSAndroid Build Coastguard Worker             const uint32_t valueIndex =
330*35238bceSAndroid Build Coastguard Worker                 gl.getProgramResourceIndex(program.getProgram(), GL_BUFFER_VARIABLE, "Input.values");
331*35238bceSAndroid Build Coastguard Worker             const InterfaceVariableInfo valueInfo =
332*35238bceSAndroid Build Coastguard Worker                 getProgramInterfaceVariableInfo(gl, program.getProgram(), GL_BUFFER_VARIABLE, valueIndex);
333*35238bceSAndroid Build Coastguard Worker 
334*35238bceSAndroid Build Coastguard Worker             gl.bindBuffer(GL_SHADER_STORAGE_BUFFER, *inputBuffer);
335*35238bceSAndroid Build Coastguard Worker             gl.bufferData(GL_SHADER_STORAGE_BUFFER, (glw::GLsizeiptr)blockInfo.dataSize, DE_NULL, GL_STATIC_DRAW);
336*35238bceSAndroid Build Coastguard Worker 
337*35238bceSAndroid Build Coastguard Worker             TCU_CHECK(valueInfo.arraySize == (uint32_t)inputValues.size());
338*35238bceSAndroid Build Coastguard Worker 
339*35238bceSAndroid Build Coastguard Worker             {
340*35238bceSAndroid Build Coastguard Worker                 const BufferMemMap bufMap(gl, GL_SHADER_STORAGE_BUFFER, 0, (int)blockInfo.dataSize, GL_MAP_WRITE_BIT);
341*35238bceSAndroid Build Coastguard Worker 
342*35238bceSAndroid Build Coastguard Worker                 for (uint32_t ndx = 0; ndx < (uint32_t)inputValues.size(); ndx++)
343*35238bceSAndroid Build Coastguard Worker                     *(uint32_t *)((uint8_t *)bufMap.getPtr() + valueInfo.offset + ndx * valueInfo.arrayStride) =
344*35238bceSAndroid Build Coastguard Worker                         inputValues[ndx];
345*35238bceSAndroid Build Coastguard Worker             }
346*35238bceSAndroid Build Coastguard Worker 
347*35238bceSAndroid Build Coastguard Worker             gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, blockInfo.bufferBinding, *inputBuffer);
348*35238bceSAndroid Build Coastguard Worker             GLU_EXPECT_NO_ERROR(gl.getError(), "Input buffer setup failed");
349*35238bceSAndroid Build Coastguard Worker         }
350*35238bceSAndroid Build Coastguard Worker 
351*35238bceSAndroid Build Coastguard Worker         // Output buffer setup
352*35238bceSAndroid Build Coastguard Worker         {
353*35238bceSAndroid Build Coastguard Worker             const uint32_t blockIndex =
354*35238bceSAndroid Build Coastguard Worker                 gl.getProgramResourceIndex(program.getProgram(), GL_SHADER_STORAGE_BLOCK, "Output");
355*35238bceSAndroid Build Coastguard Worker             const InterfaceBlockInfo blockInfo =
356*35238bceSAndroid Build Coastguard Worker                 getProgramInterfaceBlockInfo(gl, program.getProgram(), GL_SHADER_STORAGE_BLOCK, blockIndex);
357*35238bceSAndroid Build Coastguard Worker 
358*35238bceSAndroid Build Coastguard Worker             gl.bindBuffer(GL_SHADER_STORAGE_BUFFER, *outputBuffer);
359*35238bceSAndroid Build Coastguard Worker             gl.bufferData(GL_SHADER_STORAGE_BUFFER, blockInfo.dataSize, DE_NULL, GL_STREAM_READ);
360*35238bceSAndroid Build Coastguard Worker             gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, blockInfo.bufferBinding, *outputBuffer);
361*35238bceSAndroid Build Coastguard Worker             GLU_EXPECT_NO_ERROR(gl.getError(), "Output buffer setup failed");
362*35238bceSAndroid Build Coastguard Worker         }
363*35238bceSAndroid Build Coastguard Worker 
364*35238bceSAndroid Build Coastguard Worker         // Dispatch compute workload
365*35238bceSAndroid Build Coastguard Worker         gl.dispatchCompute(m_workSize[0], m_workSize[1], m_workSize[2]);
366*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(gl.getError(), "glDispatchCompute()");
367*35238bceSAndroid Build Coastguard Worker 
368*35238bceSAndroid Build Coastguard Worker         // Read back and compare
369*35238bceSAndroid Build Coastguard Worker         {
370*35238bceSAndroid Build Coastguard Worker             const uint32_t blockIndex =
371*35238bceSAndroid Build Coastguard Worker                 gl.getProgramResourceIndex(program.getProgram(), GL_SHADER_STORAGE_BLOCK, "Output");
372*35238bceSAndroid Build Coastguard Worker             const int blockSize = getProgramResourceInt(gl, program.getProgram(), GL_SHADER_STORAGE_BLOCK, blockIndex,
373*35238bceSAndroid Build Coastguard Worker                                                         GL_BUFFER_DATA_SIZE);
374*35238bceSAndroid Build Coastguard Worker             const uint32_t valueIndex =
375*35238bceSAndroid Build Coastguard Worker                 gl.getProgramResourceIndex(program.getProgram(), GL_BUFFER_VARIABLE, "Output.values");
376*35238bceSAndroid Build Coastguard Worker             const InterfaceVariableInfo valueInfo =
377*35238bceSAndroid Build Coastguard Worker                 getProgramInterfaceVariableInfo(gl, program.getProgram(), GL_BUFFER_VARIABLE, valueIndex);
378*35238bceSAndroid Build Coastguard Worker             const BufferMemMap bufMap(gl, GL_SHADER_STORAGE_BUFFER, 0, blockSize, GL_MAP_READ_BIT);
379*35238bceSAndroid Build Coastguard Worker 
380*35238bceSAndroid Build Coastguard Worker             TCU_CHECK(valueInfo.arraySize == (uint32_t)inputValues.size());
381*35238bceSAndroid Build Coastguard Worker             for (uint32_t ndx = 0; ndx < valueInfo.arraySize; ndx++)
382*35238bceSAndroid Build Coastguard Worker             {
383*35238bceSAndroid Build Coastguard Worker                 const uint32_t res = *((const uint32_t *)((const uint8_t *)bufMap.getPtr() + valueInfo.offset +
384*35238bceSAndroid Build Coastguard Worker                                                           valueInfo.arrayStride * ndx));
385*35238bceSAndroid Build Coastguard Worker                 const uint32_t ref = ~inputValues[ndx];
386*35238bceSAndroid Build Coastguard Worker 
387*35238bceSAndroid Build Coastguard Worker                 if (res != ref)
388*35238bceSAndroid Build Coastguard Worker                     throw tcu::TestError(string("Comparison failed for Output.values[") + de::toString(ndx) + "]");
389*35238bceSAndroid Build Coastguard Worker             }
390*35238bceSAndroid Build Coastguard Worker         }
391*35238bceSAndroid Build Coastguard Worker 
392*35238bceSAndroid Build Coastguard Worker         m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
393*35238bceSAndroid Build Coastguard Worker         return STOP;
394*35238bceSAndroid Build Coastguard Worker     }
395*35238bceSAndroid Build Coastguard Worker 
396*35238bceSAndroid Build Coastguard Worker private:
397*35238bceSAndroid Build Coastguard Worker     const int m_numValues;
398*35238bceSAndroid Build Coastguard Worker     const tcu::IVec3 m_localSize;
399*35238bceSAndroid Build Coastguard Worker     const tcu::IVec3 m_workSize;
400*35238bceSAndroid Build Coastguard Worker };
401*35238bceSAndroid Build Coastguard Worker 
402*35238bceSAndroid Build Coastguard Worker class InvertSSBOInPlaceCase : public TestCase
403*35238bceSAndroid Build Coastguard Worker {
404*35238bceSAndroid Build Coastguard Worker public:
InvertSSBOInPlaceCase(Context & context,const char * name,const char * description,int numValues,bool isSized,const tcu::IVec3 & localSize,const tcu::IVec3 & workSize)405*35238bceSAndroid Build Coastguard Worker     InvertSSBOInPlaceCase(Context &context, const char *name, const char *description, int numValues, bool isSized,
406*35238bceSAndroid Build Coastguard Worker                           const tcu::IVec3 &localSize, const tcu::IVec3 &workSize)
407*35238bceSAndroid Build Coastguard Worker         : TestCase(context, name, description)
408*35238bceSAndroid Build Coastguard Worker         , m_numValues(numValues)
409*35238bceSAndroid Build Coastguard Worker         , m_isSized(isSized)
410*35238bceSAndroid Build Coastguard Worker         , m_localSize(localSize)
411*35238bceSAndroid Build Coastguard Worker         , m_workSize(workSize)
412*35238bceSAndroid Build Coastguard Worker     {
413*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(m_numValues % (m_workSize[0] * m_workSize[1] * m_workSize[2] * m_localSize[0] * m_localSize[1] *
414*35238bceSAndroid Build Coastguard Worker                                  m_localSize[2]) ==
415*35238bceSAndroid Build Coastguard Worker                   0);
416*35238bceSAndroid Build Coastguard Worker     }
417*35238bceSAndroid Build Coastguard Worker 
iterate(void)418*35238bceSAndroid Build Coastguard Worker     IterateResult iterate(void)
419*35238bceSAndroid Build Coastguard Worker     {
420*35238bceSAndroid Build Coastguard Worker         const GLSLVersion glslVersion = glu::getContextTypeGLSLVersion(m_context.getRenderContext().getType());
421*35238bceSAndroid Build Coastguard Worker         std::ostringstream src;
422*35238bceSAndroid Build Coastguard Worker 
423*35238bceSAndroid Build Coastguard Worker         src << getGLSLVersionDeclaration(glslVersion) << "\n"
424*35238bceSAndroid Build Coastguard Worker             << "layout (local_size_x = " << m_localSize[0] << ", local_size_y = " << m_localSize[1]
425*35238bceSAndroid Build Coastguard Worker             << ", local_size_z = " << m_localSize[2] << ") in;\n"
426*35238bceSAndroid Build Coastguard Worker             << "layout(binding = 0) buffer InOut {\n"
427*35238bceSAndroid Build Coastguard Worker             << "    uint values[" << (m_isSized ? de::toString(m_numValues) : string("")) << "];\n"
428*35238bceSAndroid Build Coastguard Worker             << "} sb_inout;\n"
429*35238bceSAndroid Build Coastguard Worker             << "void main (void) {\n"
430*35238bceSAndroid Build Coastguard Worker             << "    uvec3 size           = gl_NumWorkGroups * gl_WorkGroupSize;\n"
431*35238bceSAndroid Build Coastguard Worker             << "    uint numValuesPerInv = uint(sb_inout.values.length()) / (size.x*size.y*size.z);\n"
432*35238bceSAndroid Build Coastguard Worker             << "    uint groupNdx        = size.x*size.y*gl_GlobalInvocationID.z + size.x*gl_GlobalInvocationID.y + "
433*35238bceSAndroid Build Coastguard Worker                "gl_GlobalInvocationID.x;\n"
434*35238bceSAndroid Build Coastguard Worker             << "    uint offset          = numValuesPerInv*groupNdx;\n"
435*35238bceSAndroid Build Coastguard Worker             << "\n"
436*35238bceSAndroid Build Coastguard Worker             << "    for (uint ndx = 0u; ndx < numValuesPerInv; ndx++)\n"
437*35238bceSAndroid Build Coastguard Worker             << "        sb_inout.values[offset + ndx] = ~sb_inout.values[offset + ndx];\n"
438*35238bceSAndroid Build Coastguard Worker             << "}\n";
439*35238bceSAndroid Build Coastguard Worker 
440*35238bceSAndroid Build Coastguard Worker         const glw::Functions &gl = m_context.getRenderContext().getFunctions();
441*35238bceSAndroid Build Coastguard Worker         const ShaderProgram program(m_context.getRenderContext(), ProgramSources()
442*35238bceSAndroid Build Coastguard Worker                                                                       << ShaderSource(SHADERTYPE_COMPUTE, src.str()));
443*35238bceSAndroid Build Coastguard Worker 
444*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << program;
445*35238bceSAndroid Build Coastguard Worker         if (!program.isOk())
446*35238bceSAndroid Build Coastguard Worker             TCU_FAIL("Compile failed");
447*35238bceSAndroid Build Coastguard Worker 
448*35238bceSAndroid Build Coastguard Worker         const Buffer outputBuffer(m_context.getRenderContext());
449*35238bceSAndroid Build Coastguard Worker         const uint32_t valueIndex =
450*35238bceSAndroid Build Coastguard Worker             gl.getProgramResourceIndex(program.getProgram(), GL_BUFFER_VARIABLE, "InOut.values");
451*35238bceSAndroid Build Coastguard Worker         const InterfaceVariableInfo valueInfo =
452*35238bceSAndroid Build Coastguard Worker             getProgramInterfaceVariableInfo(gl, program.getProgram(), GL_BUFFER_VARIABLE, valueIndex);
453*35238bceSAndroid Build Coastguard Worker         const uint32_t blockSize = valueInfo.arrayStride * (uint32_t)m_numValues;
454*35238bceSAndroid Build Coastguard Worker         std::vector<uint32_t> inputValues(m_numValues);
455*35238bceSAndroid Build Coastguard Worker 
456*35238bceSAndroid Build Coastguard Worker         // Compute input values.
457*35238bceSAndroid Build Coastguard Worker         {
458*35238bceSAndroid Build Coastguard Worker             de::Random rnd(0x82ce7f);
459*35238bceSAndroid Build Coastguard Worker             for (int ndx = 0; ndx < (int)inputValues.size(); ndx++)
460*35238bceSAndroid Build Coastguard Worker                 inputValues[ndx] = rnd.getUint32();
461*35238bceSAndroid Build Coastguard Worker         }
462*35238bceSAndroid Build Coastguard Worker 
463*35238bceSAndroid Build Coastguard Worker         TCU_CHECK(valueInfo.arraySize == (uint32_t)(m_isSized ? m_numValues : 0));
464*35238bceSAndroid Build Coastguard Worker 
465*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << TestLog::Message << "Work groups: " << m_workSize << TestLog::EndMessage;
466*35238bceSAndroid Build Coastguard Worker 
467*35238bceSAndroid Build Coastguard Worker         gl.useProgram(program.getProgram());
468*35238bceSAndroid Build Coastguard Worker 
469*35238bceSAndroid Build Coastguard Worker         // Output buffer setup
470*35238bceSAndroid Build Coastguard Worker         {
471*35238bceSAndroid Build Coastguard Worker             gl.bindBuffer(GL_SHADER_STORAGE_BUFFER, *outputBuffer);
472*35238bceSAndroid Build Coastguard Worker             gl.bufferData(GL_SHADER_STORAGE_BUFFER, blockSize, DE_NULL, GL_STREAM_DRAW);
473*35238bceSAndroid Build Coastguard Worker 
474*35238bceSAndroid Build Coastguard Worker             {
475*35238bceSAndroid Build Coastguard Worker                 const BufferMemMap bufMap(gl, GL_SHADER_STORAGE_BUFFER, 0, (int)blockSize, GL_MAP_WRITE_BIT);
476*35238bceSAndroid Build Coastguard Worker 
477*35238bceSAndroid Build Coastguard Worker                 for (uint32_t ndx = 0; ndx < (uint32_t)inputValues.size(); ndx++)
478*35238bceSAndroid Build Coastguard Worker                     *(uint32_t *)((uint8_t *)bufMap.getPtr() + valueInfo.offset + ndx * valueInfo.arrayStride) =
479*35238bceSAndroid Build Coastguard Worker                         inputValues[ndx];
480*35238bceSAndroid Build Coastguard Worker             }
481*35238bceSAndroid Build Coastguard Worker 
482*35238bceSAndroid Build Coastguard Worker             gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, *outputBuffer);
483*35238bceSAndroid Build Coastguard Worker             GLU_EXPECT_NO_ERROR(gl.getError(), "Buffer setup failed");
484*35238bceSAndroid Build Coastguard Worker         }
485*35238bceSAndroid Build Coastguard Worker 
486*35238bceSAndroid Build Coastguard Worker         // Dispatch compute workload
487*35238bceSAndroid Build Coastguard Worker         gl.dispatchCompute(m_workSize[0], m_workSize[1], m_workSize[2]);
488*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(gl.getError(), "glDispatchCompute()");
489*35238bceSAndroid Build Coastguard Worker 
490*35238bceSAndroid Build Coastguard Worker         // Read back and compare
491*35238bceSAndroid Build Coastguard Worker         {
492*35238bceSAndroid Build Coastguard Worker             const BufferMemMap bufMap(gl, GL_SHADER_STORAGE_BUFFER, 0, blockSize, GL_MAP_READ_BIT);
493*35238bceSAndroid Build Coastguard Worker 
494*35238bceSAndroid Build Coastguard Worker             for (uint32_t ndx = 0; ndx < (uint32_t)inputValues.size(); ndx++)
495*35238bceSAndroid Build Coastguard Worker             {
496*35238bceSAndroid Build Coastguard Worker                 const uint32_t res = *((const uint32_t *)((const uint8_t *)bufMap.getPtr() + valueInfo.offset +
497*35238bceSAndroid Build Coastguard Worker                                                           valueInfo.arrayStride * ndx));
498*35238bceSAndroid Build Coastguard Worker                 const uint32_t ref = ~inputValues[ndx];
499*35238bceSAndroid Build Coastguard Worker 
500*35238bceSAndroid Build Coastguard Worker                 if (res != ref)
501*35238bceSAndroid Build Coastguard Worker                     throw tcu::TestError(string("Comparison failed for InOut.values[") + de::toString(ndx) + "]");
502*35238bceSAndroid Build Coastguard Worker             }
503*35238bceSAndroid Build Coastguard Worker         }
504*35238bceSAndroid Build Coastguard Worker 
505*35238bceSAndroid Build Coastguard Worker         m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
506*35238bceSAndroid Build Coastguard Worker         return STOP;
507*35238bceSAndroid Build Coastguard Worker     }
508*35238bceSAndroid Build Coastguard Worker 
509*35238bceSAndroid Build Coastguard Worker private:
510*35238bceSAndroid Build Coastguard Worker     const int m_numValues;
511*35238bceSAndroid Build Coastguard Worker     const bool m_isSized;
512*35238bceSAndroid Build Coastguard Worker     const tcu::IVec3 m_localSize;
513*35238bceSAndroid Build Coastguard Worker     const tcu::IVec3 m_workSize;
514*35238bceSAndroid Build Coastguard Worker };
515*35238bceSAndroid Build Coastguard Worker 
516*35238bceSAndroid Build Coastguard Worker class WriteToMultipleSSBOCase : public TestCase
517*35238bceSAndroid Build Coastguard Worker {
518*35238bceSAndroid Build Coastguard Worker public:
WriteToMultipleSSBOCase(Context & context,const char * name,const char * description,int numValues,bool isSized,const tcu::IVec3 & localSize,const tcu::IVec3 & workSize)519*35238bceSAndroid Build Coastguard Worker     WriteToMultipleSSBOCase(Context &context, const char *name, const char *description, int numValues, bool isSized,
520*35238bceSAndroid Build Coastguard Worker                             const tcu::IVec3 &localSize, const tcu::IVec3 &workSize)
521*35238bceSAndroid Build Coastguard Worker         : TestCase(context, name, description)
522*35238bceSAndroid Build Coastguard Worker         , m_numValues(numValues)
523*35238bceSAndroid Build Coastguard Worker         , m_isSized(isSized)
524*35238bceSAndroid Build Coastguard Worker         , m_localSize(localSize)
525*35238bceSAndroid Build Coastguard Worker         , m_workSize(workSize)
526*35238bceSAndroid Build Coastguard Worker     {
527*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(m_numValues % (m_workSize[0] * m_workSize[1] * m_workSize[2] * m_localSize[0] * m_localSize[1] *
528*35238bceSAndroid Build Coastguard Worker                                  m_localSize[2]) ==
529*35238bceSAndroid Build Coastguard Worker                   0);
530*35238bceSAndroid Build Coastguard Worker     }
531*35238bceSAndroid Build Coastguard Worker 
iterate(void)532*35238bceSAndroid Build Coastguard Worker     IterateResult iterate(void)
533*35238bceSAndroid Build Coastguard Worker     {
534*35238bceSAndroid Build Coastguard Worker         const GLSLVersion glslVersion = glu::getContextTypeGLSLVersion(m_context.getRenderContext().getType());
535*35238bceSAndroid Build Coastguard Worker         std::ostringstream src;
536*35238bceSAndroid Build Coastguard Worker 
537*35238bceSAndroid Build Coastguard Worker         src << getGLSLVersionDeclaration(glslVersion) << "\n"
538*35238bceSAndroid Build Coastguard Worker             << "layout (local_size_x = " << m_localSize[0] << ", local_size_y = " << m_localSize[1]
539*35238bceSAndroid Build Coastguard Worker             << ", local_size_z = " << m_localSize[2] << ") in;\n"
540*35238bceSAndroid Build Coastguard Worker             << "layout(binding = 0) buffer Out0 {\n"
541*35238bceSAndroid Build Coastguard Worker             << "    uint values[" << (m_isSized ? de::toString(m_numValues) : string("")) << "];\n"
542*35238bceSAndroid Build Coastguard Worker             << "} sb_out0;\n"
543*35238bceSAndroid Build Coastguard Worker             << "layout(binding = 1) buffer Out1 {\n"
544*35238bceSAndroid Build Coastguard Worker             << "    uint values[" << (m_isSized ? de::toString(m_numValues) : string("")) << "];\n"
545*35238bceSAndroid Build Coastguard Worker             << "} sb_out1;\n"
546*35238bceSAndroid Build Coastguard Worker             << "void main (void) {\n"
547*35238bceSAndroid Build Coastguard Worker             << "    uvec3 size      = gl_NumWorkGroups * gl_WorkGroupSize;\n"
548*35238bceSAndroid Build Coastguard Worker             << "    uint groupNdx   = size.x*size.y*gl_GlobalInvocationID.z + size.x*gl_GlobalInvocationID.y + "
549*35238bceSAndroid Build Coastguard Worker                "gl_GlobalInvocationID.x;\n"
550*35238bceSAndroid Build Coastguard Worker             << "\n"
551*35238bceSAndroid Build Coastguard Worker             << "    {\n"
552*35238bceSAndroid Build Coastguard Worker             << "        uint numValuesPerInv = uint(sb_out0.values.length()) / (size.x*size.y*size.z);\n"
553*35238bceSAndroid Build Coastguard Worker             << "        uint offset          = numValuesPerInv*groupNdx;\n"
554*35238bceSAndroid Build Coastguard Worker             << "\n"
555*35238bceSAndroid Build Coastguard Worker             << "        for (uint ndx = 0u; ndx < numValuesPerInv; ndx++)\n"
556*35238bceSAndroid Build Coastguard Worker             << "            sb_out0.values[offset + ndx] = offset + ndx;\n"
557*35238bceSAndroid Build Coastguard Worker             << "    }\n"
558*35238bceSAndroid Build Coastguard Worker             << "    {\n"
559*35238bceSAndroid Build Coastguard Worker             << "        uint numValuesPerInv = uint(sb_out1.values.length()) / (size.x*size.y*size.z);\n"
560*35238bceSAndroid Build Coastguard Worker             << "        uint offset          = numValuesPerInv*groupNdx;\n"
561*35238bceSAndroid Build Coastguard Worker             << "\n"
562*35238bceSAndroid Build Coastguard Worker             << "        for (uint ndx = 0u; ndx < numValuesPerInv; ndx++)\n"
563*35238bceSAndroid Build Coastguard Worker             << "            sb_out1.values[offset + ndx] = uint(sb_out1.values.length()) - offset - ndx;\n"
564*35238bceSAndroid Build Coastguard Worker             << "    }\n"
565*35238bceSAndroid Build Coastguard Worker             << "}\n";
566*35238bceSAndroid Build Coastguard Worker 
567*35238bceSAndroid Build Coastguard Worker         const glw::Functions &gl = m_context.getRenderContext().getFunctions();
568*35238bceSAndroid Build Coastguard Worker         const ShaderProgram program(m_context.getRenderContext(), ProgramSources()
569*35238bceSAndroid Build Coastguard Worker                                                                       << ShaderSource(SHADERTYPE_COMPUTE, src.str()));
570*35238bceSAndroid Build Coastguard Worker 
571*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << program;
572*35238bceSAndroid Build Coastguard Worker         if (!program.isOk())
573*35238bceSAndroid Build Coastguard Worker             TCU_FAIL("Compile failed");
574*35238bceSAndroid Build Coastguard Worker 
575*35238bceSAndroid Build Coastguard Worker         const Buffer outputBuffer0(m_context.getRenderContext());
576*35238bceSAndroid Build Coastguard Worker         const uint32_t value0Index =
577*35238bceSAndroid Build Coastguard Worker             gl.getProgramResourceIndex(program.getProgram(), GL_BUFFER_VARIABLE, "Out0.values");
578*35238bceSAndroid Build Coastguard Worker         const InterfaceVariableInfo value0Info =
579*35238bceSAndroid Build Coastguard Worker             getProgramInterfaceVariableInfo(gl, program.getProgram(), GL_BUFFER_VARIABLE, value0Index);
580*35238bceSAndroid Build Coastguard Worker         const uint32_t block0Size = value0Info.arrayStride * (uint32_t)m_numValues;
581*35238bceSAndroid Build Coastguard Worker 
582*35238bceSAndroid Build Coastguard Worker         const Buffer outputBuffer1(m_context.getRenderContext());
583*35238bceSAndroid Build Coastguard Worker         const uint32_t value1Index =
584*35238bceSAndroid Build Coastguard Worker             gl.getProgramResourceIndex(program.getProgram(), GL_BUFFER_VARIABLE, "Out1.values");
585*35238bceSAndroid Build Coastguard Worker         const InterfaceVariableInfo value1Info =
586*35238bceSAndroid Build Coastguard Worker             getProgramInterfaceVariableInfo(gl, program.getProgram(), GL_BUFFER_VARIABLE, value1Index);
587*35238bceSAndroid Build Coastguard Worker         const uint32_t block1Size = value1Info.arrayStride * (uint32_t)m_numValues;
588*35238bceSAndroid Build Coastguard Worker 
589*35238bceSAndroid Build Coastguard Worker         TCU_CHECK(value0Info.arraySize == (uint32_t)(m_isSized ? m_numValues : 0));
590*35238bceSAndroid Build Coastguard Worker         TCU_CHECK(value1Info.arraySize == (uint32_t)(m_isSized ? m_numValues : 0));
591*35238bceSAndroid Build Coastguard Worker 
592*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << TestLog::Message << "Work groups: " << m_workSize << TestLog::EndMessage;
593*35238bceSAndroid Build Coastguard Worker 
594*35238bceSAndroid Build Coastguard Worker         gl.useProgram(program.getProgram());
595*35238bceSAndroid Build Coastguard Worker 
596*35238bceSAndroid Build Coastguard Worker         // Output buffer setup
597*35238bceSAndroid Build Coastguard Worker         {
598*35238bceSAndroid Build Coastguard Worker             gl.bindBuffer(GL_SHADER_STORAGE_BUFFER, *outputBuffer0);
599*35238bceSAndroid Build Coastguard Worker             gl.bufferData(GL_SHADER_STORAGE_BUFFER, block0Size, DE_NULL, GL_STREAM_DRAW);
600*35238bceSAndroid Build Coastguard Worker 
601*35238bceSAndroid Build Coastguard Worker             gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, *outputBuffer0);
602*35238bceSAndroid Build Coastguard Worker             GLU_EXPECT_NO_ERROR(gl.getError(), "Buffer setup failed");
603*35238bceSAndroid Build Coastguard Worker         }
604*35238bceSAndroid Build Coastguard Worker         {
605*35238bceSAndroid Build Coastguard Worker             gl.bindBuffer(GL_SHADER_STORAGE_BUFFER, *outputBuffer1);
606*35238bceSAndroid Build Coastguard Worker             gl.bufferData(GL_SHADER_STORAGE_BUFFER, block1Size, DE_NULL, GL_STREAM_DRAW);
607*35238bceSAndroid Build Coastguard Worker 
608*35238bceSAndroid Build Coastguard Worker             gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, *outputBuffer1);
609*35238bceSAndroid Build Coastguard Worker             GLU_EXPECT_NO_ERROR(gl.getError(), "Buffer setup failed");
610*35238bceSAndroid Build Coastguard Worker         }
611*35238bceSAndroid Build Coastguard Worker 
612*35238bceSAndroid Build Coastguard Worker         // Dispatch compute workload
613*35238bceSAndroid Build Coastguard Worker         gl.dispatchCompute(m_workSize[0], m_workSize[1], m_workSize[2]);
614*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(gl.getError(), "glDispatchCompute()");
615*35238bceSAndroid Build Coastguard Worker 
616*35238bceSAndroid Build Coastguard Worker         // Read back and compare
617*35238bceSAndroid Build Coastguard Worker         gl.bindBuffer(GL_SHADER_STORAGE_BUFFER, *outputBuffer0);
618*35238bceSAndroid Build Coastguard Worker         {
619*35238bceSAndroid Build Coastguard Worker             const BufferMemMap bufMap(gl, GL_SHADER_STORAGE_BUFFER, 0, block0Size, GL_MAP_READ_BIT);
620*35238bceSAndroid Build Coastguard Worker 
621*35238bceSAndroid Build Coastguard Worker             for (uint32_t ndx = 0; ndx < (uint32_t)m_numValues; ndx++)
622*35238bceSAndroid Build Coastguard Worker             {
623*35238bceSAndroid Build Coastguard Worker                 const uint32_t res = *((const uint32_t *)((const uint8_t *)bufMap.getPtr() + value0Info.offset +
624*35238bceSAndroid Build Coastguard Worker                                                           value0Info.arrayStride * ndx));
625*35238bceSAndroid Build Coastguard Worker                 const uint32_t ref = ndx;
626*35238bceSAndroid Build Coastguard Worker 
627*35238bceSAndroid Build Coastguard Worker                 if (res != ref)
628*35238bceSAndroid Build Coastguard Worker                     throw tcu::TestError(string("Comparison failed for Out0.values[") + de::toString(ndx) +
629*35238bceSAndroid Build Coastguard Worker                                          "] res=" + de::toString(res) + " ref=" + de::toString(ref));
630*35238bceSAndroid Build Coastguard Worker             }
631*35238bceSAndroid Build Coastguard Worker         }
632*35238bceSAndroid Build Coastguard Worker         gl.bindBuffer(GL_SHADER_STORAGE_BUFFER, *outputBuffer1);
633*35238bceSAndroid Build Coastguard Worker         {
634*35238bceSAndroid Build Coastguard Worker             const BufferMemMap bufMap(gl, GL_SHADER_STORAGE_BUFFER, 0, block1Size, GL_MAP_READ_BIT);
635*35238bceSAndroid Build Coastguard Worker 
636*35238bceSAndroid Build Coastguard Worker             for (uint32_t ndx = 0; ndx < (uint32_t)m_numValues; ndx++)
637*35238bceSAndroid Build Coastguard Worker             {
638*35238bceSAndroid Build Coastguard Worker                 const uint32_t res = *((const uint32_t *)((const uint8_t *)bufMap.getPtr() + value1Info.offset +
639*35238bceSAndroid Build Coastguard Worker                                                           value1Info.arrayStride * ndx));
640*35238bceSAndroid Build Coastguard Worker                 const uint32_t ref = m_numValues - ndx;
641*35238bceSAndroid Build Coastguard Worker 
642*35238bceSAndroid Build Coastguard Worker                 if (res != ref)
643*35238bceSAndroid Build Coastguard Worker                     throw tcu::TestError(string("Comparison failed for Out1.values[") + de::toString(ndx) +
644*35238bceSAndroid Build Coastguard Worker                                          "] res=" + de::toString(res) + " ref=" + de::toString(ref));
645*35238bceSAndroid Build Coastguard Worker             }
646*35238bceSAndroid Build Coastguard Worker         }
647*35238bceSAndroid Build Coastguard Worker         m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
648*35238bceSAndroid Build Coastguard Worker         return STOP;
649*35238bceSAndroid Build Coastguard Worker     }
650*35238bceSAndroid Build Coastguard Worker 
651*35238bceSAndroid Build Coastguard Worker private:
652*35238bceSAndroid Build Coastguard Worker     const int m_numValues;
653*35238bceSAndroid Build Coastguard Worker     const bool m_isSized;
654*35238bceSAndroid Build Coastguard Worker     const tcu::IVec3 m_localSize;
655*35238bceSAndroid Build Coastguard Worker     const tcu::IVec3 m_workSize;
656*35238bceSAndroid Build Coastguard Worker };
657*35238bceSAndroid Build Coastguard Worker 
658*35238bceSAndroid Build Coastguard Worker class SSBOLocalBarrierCase : public TestCase
659*35238bceSAndroid Build Coastguard Worker {
660*35238bceSAndroid Build Coastguard Worker public:
SSBOLocalBarrierCase(Context & context,const char * name,const char * description,const tcu::IVec3 & localSize,const tcu::IVec3 & workSize)661*35238bceSAndroid Build Coastguard Worker     SSBOLocalBarrierCase(Context &context, const char *name, const char *description, const tcu::IVec3 &localSize,
662*35238bceSAndroid Build Coastguard Worker                          const tcu::IVec3 &workSize)
663*35238bceSAndroid Build Coastguard Worker         : TestCase(context, name, description)
664*35238bceSAndroid Build Coastguard Worker         , m_localSize(localSize)
665*35238bceSAndroid Build Coastguard Worker         , m_workSize(workSize)
666*35238bceSAndroid Build Coastguard Worker     {
667*35238bceSAndroid Build Coastguard Worker     }
668*35238bceSAndroid Build Coastguard Worker 
iterate(void)669*35238bceSAndroid Build Coastguard Worker     IterateResult iterate(void)
670*35238bceSAndroid Build Coastguard Worker     {
671*35238bceSAndroid Build Coastguard Worker         const glw::Functions &gl = m_context.getRenderContext().getFunctions();
672*35238bceSAndroid Build Coastguard Worker         const Buffer outputBuffer(m_context.getRenderContext());
673*35238bceSAndroid Build Coastguard Worker         const int workGroupSize  = m_localSize[0] * m_localSize[1] * m_localSize[2];
674*35238bceSAndroid Build Coastguard Worker         const int workGroupCount = m_workSize[0] * m_workSize[1] * m_workSize[2];
675*35238bceSAndroid Build Coastguard Worker         const int numValues      = workGroupSize * workGroupCount;
676*35238bceSAndroid Build Coastguard Worker 
677*35238bceSAndroid Build Coastguard Worker         const GLSLVersion glslVersion = glu::getContextTypeGLSLVersion(m_context.getRenderContext().getType());
678*35238bceSAndroid Build Coastguard Worker         std::ostringstream src;
679*35238bceSAndroid Build Coastguard Worker 
680*35238bceSAndroid Build Coastguard Worker         src << getGLSLVersionDeclaration(glslVersion) << "\n"
681*35238bceSAndroid Build Coastguard Worker             << "layout (local_size_x = " << m_localSize[0] << ", local_size_y = " << m_localSize[1]
682*35238bceSAndroid Build Coastguard Worker             << ", local_size_z = " << m_localSize[2] << ") in;\n"
683*35238bceSAndroid Build Coastguard Worker             << "layout(binding = 0) buffer Output {\n"
684*35238bceSAndroid Build Coastguard Worker             << "    coherent uint values[" << numValues << "];\n"
685*35238bceSAndroid Build Coastguard Worker             << "} sb_out;\n\n"
686*35238bceSAndroid Build Coastguard Worker             << "shared uint offsets[" << workGroupSize << "];\n\n"
687*35238bceSAndroid Build Coastguard Worker             << "void main (void) {\n"
688*35238bceSAndroid Build Coastguard Worker             << "    uint localSize  = gl_WorkGroupSize.x*gl_WorkGroupSize.y*gl_WorkGroupSize.z;\n"
689*35238bceSAndroid Build Coastguard Worker             << "    uint globalNdx  = gl_NumWorkGroups.x*gl_NumWorkGroups.y*gl_WorkGroupID.z + "
690*35238bceSAndroid Build Coastguard Worker                "gl_NumWorkGroups.x*gl_WorkGroupID.y + gl_WorkGroupID.x;\n"
691*35238bceSAndroid Build Coastguard Worker             << "    uint globalOffs = localSize*globalNdx;\n"
692*35238bceSAndroid Build Coastguard Worker             << "    uint localOffs  = gl_WorkGroupSize.x*gl_WorkGroupSize.y*gl_LocalInvocationID.z + "
693*35238bceSAndroid Build Coastguard Worker                "gl_WorkGroupSize.x*gl_LocalInvocationID.y + gl_LocalInvocationID.x;\n"
694*35238bceSAndroid Build Coastguard Worker             << "\n"
695*35238bceSAndroid Build Coastguard Worker             << "    sb_out.values[globalOffs + localOffs] = globalOffs;\n"
696*35238bceSAndroid Build Coastguard Worker             << "    memoryBarrierBuffer();\n"
697*35238bceSAndroid Build Coastguard Worker             << "    barrier();\n"
698*35238bceSAndroid Build Coastguard Worker             << "    sb_out.values[globalOffs + ((localOffs+1u)%localSize)] += localOffs;\n"
699*35238bceSAndroid Build Coastguard Worker             << "    memoryBarrierBuffer();\n"
700*35238bceSAndroid Build Coastguard Worker             << "    barrier();\n"
701*35238bceSAndroid Build Coastguard Worker             << "    sb_out.values[globalOffs + ((localOffs+2u)%localSize)] += localOffs;\n"
702*35238bceSAndroid Build Coastguard Worker             << "}\n";
703*35238bceSAndroid Build Coastguard Worker 
704*35238bceSAndroid Build Coastguard Worker         const ShaderProgram program(m_context.getRenderContext(), ProgramSources() << ComputeSource(src.str()));
705*35238bceSAndroid Build Coastguard Worker 
706*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << program;
707*35238bceSAndroid Build Coastguard Worker         if (!program.isOk())
708*35238bceSAndroid Build Coastguard Worker             TCU_FAIL("Compile failed");
709*35238bceSAndroid Build Coastguard Worker 
710*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << TestLog::Message << "Work groups: " << m_workSize << TestLog::EndMessage;
711*35238bceSAndroid Build Coastguard Worker 
712*35238bceSAndroid Build Coastguard Worker         gl.useProgram(program.getProgram());
713*35238bceSAndroid Build Coastguard Worker 
714*35238bceSAndroid Build Coastguard Worker         // Output buffer setup
715*35238bceSAndroid Build Coastguard Worker         {
716*35238bceSAndroid Build Coastguard Worker             const uint32_t blockIndex =
717*35238bceSAndroid Build Coastguard Worker                 gl.getProgramResourceIndex(program.getProgram(), GL_SHADER_STORAGE_BLOCK, "Output");
718*35238bceSAndroid Build Coastguard Worker             const int blockSize = getProgramResourceInt(gl, program.getProgram(), GL_SHADER_STORAGE_BLOCK, blockIndex,
719*35238bceSAndroid Build Coastguard Worker                                                         GL_BUFFER_DATA_SIZE);
720*35238bceSAndroid Build Coastguard Worker 
721*35238bceSAndroid Build Coastguard Worker             gl.bindBuffer(GL_SHADER_STORAGE_BUFFER, *outputBuffer);
722*35238bceSAndroid Build Coastguard Worker             gl.bufferData(GL_SHADER_STORAGE_BUFFER, blockSize, DE_NULL, GL_STREAM_READ);
723*35238bceSAndroid Build Coastguard Worker             gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, *outputBuffer);
724*35238bceSAndroid Build Coastguard Worker             GLU_EXPECT_NO_ERROR(gl.getError(), "Output buffer setup failed");
725*35238bceSAndroid Build Coastguard Worker         }
726*35238bceSAndroid Build Coastguard Worker 
727*35238bceSAndroid Build Coastguard Worker         // Dispatch compute workload
728*35238bceSAndroid Build Coastguard Worker         gl.dispatchCompute(m_workSize[0], m_workSize[1], m_workSize[2]);
729*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(gl.getError(), "glDispatchCompute()");
730*35238bceSAndroid Build Coastguard Worker 
731*35238bceSAndroid Build Coastguard Worker         // Read back and compare
732*35238bceSAndroid Build Coastguard Worker         {
733*35238bceSAndroid Build Coastguard Worker             const uint32_t blockIndex =
734*35238bceSAndroid Build Coastguard Worker                 gl.getProgramResourceIndex(program.getProgram(), GL_SHADER_STORAGE_BLOCK, "Output");
735*35238bceSAndroid Build Coastguard Worker             const int blockSize = getProgramResourceInt(gl, program.getProgram(), GL_SHADER_STORAGE_BLOCK, blockIndex,
736*35238bceSAndroid Build Coastguard Worker                                                         GL_BUFFER_DATA_SIZE);
737*35238bceSAndroid Build Coastguard Worker             const uint32_t valueIndex =
738*35238bceSAndroid Build Coastguard Worker                 gl.getProgramResourceIndex(program.getProgram(), GL_BUFFER_VARIABLE, "Output.values");
739*35238bceSAndroid Build Coastguard Worker             const InterfaceVariableInfo valueInfo =
740*35238bceSAndroid Build Coastguard Worker                 getProgramInterfaceVariableInfo(gl, program.getProgram(), GL_BUFFER_VARIABLE, valueIndex);
741*35238bceSAndroid Build Coastguard Worker             const BufferMemMap bufMap(gl, GL_SHADER_STORAGE_BUFFER, 0, blockSize, GL_MAP_READ_BIT);
742*35238bceSAndroid Build Coastguard Worker 
743*35238bceSAndroid Build Coastguard Worker             for (int groupNdx = 0; groupNdx < workGroupCount; groupNdx++)
744*35238bceSAndroid Build Coastguard Worker             {
745*35238bceSAndroid Build Coastguard Worker                 for (int localOffs = 0; localOffs < workGroupSize; localOffs++)
746*35238bceSAndroid Build Coastguard Worker                 {
747*35238bceSAndroid Build Coastguard Worker                     const int globalOffs = groupNdx * workGroupSize;
748*35238bceSAndroid Build Coastguard Worker                     const uint32_t res   = *((const uint32_t *)((const uint8_t *)bufMap.getPtr() + valueInfo.offset +
749*35238bceSAndroid Build Coastguard Worker                                                               valueInfo.arrayStride * (globalOffs + localOffs)));
750*35238bceSAndroid Build Coastguard Worker                     const int offs0      = localOffs - 1 < 0 ? ((localOffs + workGroupSize - 1) % workGroupSize) :
751*35238bceSAndroid Build Coastguard Worker                                                                ((localOffs - 1) % workGroupSize);
752*35238bceSAndroid Build Coastguard Worker                     const int offs1      = localOffs - 2 < 0 ? ((localOffs + workGroupSize - 2) % workGroupSize) :
753*35238bceSAndroid Build Coastguard Worker                                                                ((localOffs - 2) % workGroupSize);
754*35238bceSAndroid Build Coastguard Worker                     const uint32_t ref   = (uint32_t)(globalOffs + offs0 + offs1);
755*35238bceSAndroid Build Coastguard Worker 
756*35238bceSAndroid Build Coastguard Worker                     if (res != ref)
757*35238bceSAndroid Build Coastguard Worker                         throw tcu::TestError(string("Comparison failed for Output.values[") +
758*35238bceSAndroid Build Coastguard Worker                                              de::toString(globalOffs + localOffs) + "]");
759*35238bceSAndroid Build Coastguard Worker                 }
760*35238bceSAndroid Build Coastguard Worker             }
761*35238bceSAndroid Build Coastguard Worker         }
762*35238bceSAndroid Build Coastguard Worker 
763*35238bceSAndroid Build Coastguard Worker         m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
764*35238bceSAndroid Build Coastguard Worker         return STOP;
765*35238bceSAndroid Build Coastguard Worker     }
766*35238bceSAndroid Build Coastguard Worker 
767*35238bceSAndroid Build Coastguard Worker private:
768*35238bceSAndroid Build Coastguard Worker     const tcu::IVec3 m_localSize;
769*35238bceSAndroid Build Coastguard Worker     const tcu::IVec3 m_workSize;
770*35238bceSAndroid Build Coastguard Worker };
771*35238bceSAndroid Build Coastguard Worker 
772*35238bceSAndroid Build Coastguard Worker class SSBOBarrierCase : public TestCase
773*35238bceSAndroid Build Coastguard Worker {
774*35238bceSAndroid Build Coastguard Worker public:
SSBOBarrierCase(Context & context,const char * name,const char * description,const tcu::IVec3 & workSize)775*35238bceSAndroid Build Coastguard Worker     SSBOBarrierCase(Context &context, const char *name, const char *description, const tcu::IVec3 &workSize)
776*35238bceSAndroid Build Coastguard Worker         : TestCase(context, name, description)
777*35238bceSAndroid Build Coastguard Worker         , m_workSize(workSize)
778*35238bceSAndroid Build Coastguard Worker     {
779*35238bceSAndroid Build Coastguard Worker     }
780*35238bceSAndroid Build Coastguard Worker 
iterate(void)781*35238bceSAndroid Build Coastguard Worker     IterateResult iterate(void)
782*35238bceSAndroid Build Coastguard Worker     {
783*35238bceSAndroid Build Coastguard Worker         const GLSLVersion glslVersion = glu::getContextTypeGLSLVersion(m_context.getRenderContext().getType());
784*35238bceSAndroid Build Coastguard Worker         const char *const glslVersionDeclaration = getGLSLVersionDeclaration(glslVersion);
785*35238bceSAndroid Build Coastguard Worker 
786*35238bceSAndroid Build Coastguard Worker         std::ostringstream src0;
787*35238bceSAndroid Build Coastguard Worker         src0 << glslVersionDeclaration << "\n"
788*35238bceSAndroid Build Coastguard Worker              << "layout (local_size_x = 1) in;\n"
789*35238bceSAndroid Build Coastguard Worker                 "uniform uint u_baseVal;\n"
790*35238bceSAndroid Build Coastguard Worker                 "layout(binding = 1) buffer Output {\n"
791*35238bceSAndroid Build Coastguard Worker                 "    uint values[];\n"
792*35238bceSAndroid Build Coastguard Worker                 "};\n"
793*35238bceSAndroid Build Coastguard Worker                 "void main (void) {\n"
794*35238bceSAndroid Build Coastguard Worker                 "    uint offset = gl_NumWorkGroups.x*gl_NumWorkGroups.y*gl_WorkGroupID.z + "
795*35238bceSAndroid Build Coastguard Worker                 "gl_NumWorkGroups.x*gl_WorkGroupID.y + gl_WorkGroupID.x;\n"
796*35238bceSAndroid Build Coastguard Worker                 "    values[offset] = u_baseVal+offset;\n"
797*35238bceSAndroid Build Coastguard Worker                 "}\n";
798*35238bceSAndroid Build Coastguard Worker 
799*35238bceSAndroid Build Coastguard Worker         std::ostringstream src1;
800*35238bceSAndroid Build Coastguard Worker         src1 << glslVersionDeclaration << "\n"
801*35238bceSAndroid Build Coastguard Worker              << "layout (local_size_x = 1) in;\n"
802*35238bceSAndroid Build Coastguard Worker                 "uniform uint u_baseVal;\n"
803*35238bceSAndroid Build Coastguard Worker                 "layout(binding = 1) buffer Input {\n"
804*35238bceSAndroid Build Coastguard Worker                 "    uint values[];\n"
805*35238bceSAndroid Build Coastguard Worker                 "};\n"
806*35238bceSAndroid Build Coastguard Worker                 "layout(binding = 0) buffer Output {\n"
807*35238bceSAndroid Build Coastguard Worker                 "    coherent uint sum;\n"
808*35238bceSAndroid Build Coastguard Worker                 "};\n"
809*35238bceSAndroid Build Coastguard Worker                 "void main (void) {\n"
810*35238bceSAndroid Build Coastguard Worker                 "    uint offset = gl_NumWorkGroups.x*gl_NumWorkGroups.y*gl_WorkGroupID.z + "
811*35238bceSAndroid Build Coastguard Worker                 "gl_NumWorkGroups.x*gl_WorkGroupID.y + gl_WorkGroupID.x;\n"
812*35238bceSAndroid Build Coastguard Worker                 "    uint value  = values[offset];\n"
813*35238bceSAndroid Build Coastguard Worker                 "    atomicAdd(sum, value);\n"
814*35238bceSAndroid Build Coastguard Worker                 "}\n";
815*35238bceSAndroid Build Coastguard Worker 
816*35238bceSAndroid Build Coastguard Worker         const ShaderProgram program0(m_context.getRenderContext(), ProgramSources() << ComputeSource(src0.str()));
817*35238bceSAndroid Build Coastguard Worker         const ShaderProgram program1(m_context.getRenderContext(), ProgramSources() << ComputeSource(src1.str()));
818*35238bceSAndroid Build Coastguard Worker 
819*35238bceSAndroid Build Coastguard Worker         const glw::Functions &gl = m_context.getRenderContext().getFunctions();
820*35238bceSAndroid Build Coastguard Worker         const Buffer tempBuffer(m_context.getRenderContext());
821*35238bceSAndroid Build Coastguard Worker         const Buffer outputBuffer(m_context.getRenderContext());
822*35238bceSAndroid Build Coastguard Worker         const uint32_t baseValue = 127;
823*35238bceSAndroid Build Coastguard Worker 
824*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << program0 << program1;
825*35238bceSAndroid Build Coastguard Worker         if (!program0.isOk() || !program1.isOk())
826*35238bceSAndroid Build Coastguard Worker             TCU_FAIL("Compile failed");
827*35238bceSAndroid Build Coastguard Worker 
828*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << TestLog::Message << "Work groups: " << m_workSize << TestLog::EndMessage;
829*35238bceSAndroid Build Coastguard Worker 
830*35238bceSAndroid Build Coastguard Worker         // Temp buffer setup
831*35238bceSAndroid Build Coastguard Worker         {
832*35238bceSAndroid Build Coastguard Worker             const uint32_t valueIndex =
833*35238bceSAndroid Build Coastguard Worker                 gl.getProgramResourceIndex(program0.getProgram(), GL_BUFFER_VARIABLE, "values[0]");
834*35238bceSAndroid Build Coastguard Worker             const InterfaceVariableInfo valueInfo =
835*35238bceSAndroid Build Coastguard Worker                 getProgramInterfaceVariableInfo(gl, program0.getProgram(), GL_BUFFER_VARIABLE, valueIndex);
836*35238bceSAndroid Build Coastguard Worker             const uint32_t bufferSize = valueInfo.arrayStride * m_workSize[0] * m_workSize[1] * m_workSize[2];
837*35238bceSAndroid Build Coastguard Worker 
838*35238bceSAndroid Build Coastguard Worker             gl.bindBuffer(GL_SHADER_STORAGE_BUFFER, *tempBuffer);
839*35238bceSAndroid Build Coastguard Worker             gl.bufferData(GL_SHADER_STORAGE_BUFFER, (glw::GLsizeiptr)bufferSize, DE_NULL, GL_STATIC_DRAW);
840*35238bceSAndroid Build Coastguard Worker             gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, *tempBuffer);
841*35238bceSAndroid Build Coastguard Worker             GLU_EXPECT_NO_ERROR(gl.getError(), "Temp buffer setup failed");
842*35238bceSAndroid Build Coastguard Worker         }
843*35238bceSAndroid Build Coastguard Worker 
844*35238bceSAndroid Build Coastguard Worker         // Output buffer setup
845*35238bceSAndroid Build Coastguard Worker         {
846*35238bceSAndroid Build Coastguard Worker             const uint32_t blockIndex =
847*35238bceSAndroid Build Coastguard Worker                 gl.getProgramResourceIndex(program1.getProgram(), GL_SHADER_STORAGE_BLOCK, "Output");
848*35238bceSAndroid Build Coastguard Worker             const int blockSize = getProgramResourceInt(gl, program1.getProgram(), GL_SHADER_STORAGE_BLOCK, blockIndex,
849*35238bceSAndroid Build Coastguard Worker                                                         GL_BUFFER_DATA_SIZE);
850*35238bceSAndroid Build Coastguard Worker 
851*35238bceSAndroid Build Coastguard Worker             gl.bindBuffer(GL_SHADER_STORAGE_BUFFER, *outputBuffer);
852*35238bceSAndroid Build Coastguard Worker             gl.bufferData(GL_SHADER_STORAGE_BUFFER, blockSize, DE_NULL, GL_STREAM_READ);
853*35238bceSAndroid Build Coastguard Worker 
854*35238bceSAndroid Build Coastguard Worker             {
855*35238bceSAndroid Build Coastguard Worker                 const BufferMemMap bufMap(gl, GL_SHADER_STORAGE_BUFFER, 0, blockSize, GL_MAP_WRITE_BIT);
856*35238bceSAndroid Build Coastguard Worker                 deMemset(bufMap.getPtr(), 0, blockSize);
857*35238bceSAndroid Build Coastguard Worker             }
858*35238bceSAndroid Build Coastguard Worker 
859*35238bceSAndroid Build Coastguard Worker             gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, *outputBuffer);
860*35238bceSAndroid Build Coastguard Worker             GLU_EXPECT_NO_ERROR(gl.getError(), "Output buffer setup failed");
861*35238bceSAndroid Build Coastguard Worker         }
862*35238bceSAndroid Build Coastguard Worker 
863*35238bceSAndroid Build Coastguard Worker         // Dispatch compute workload
864*35238bceSAndroid Build Coastguard Worker         gl.useProgram(program0.getProgram());
865*35238bceSAndroid Build Coastguard Worker         gl.uniform1ui(gl.getUniformLocation(program0.getProgram(), "u_baseVal"), baseValue);
866*35238bceSAndroid Build Coastguard Worker         gl.dispatchCompute(m_workSize[0], m_workSize[1], m_workSize[2]);
867*35238bceSAndroid Build Coastguard Worker         gl.memoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
868*35238bceSAndroid Build Coastguard Worker         gl.useProgram(program1.getProgram());
869*35238bceSAndroid Build Coastguard Worker         gl.dispatchCompute(m_workSize[0], m_workSize[1], m_workSize[2]);
870*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to dispatch commands");
871*35238bceSAndroid Build Coastguard Worker 
872*35238bceSAndroid Build Coastguard Worker         // Read back and compare
873*35238bceSAndroid Build Coastguard Worker         {
874*35238bceSAndroid Build Coastguard Worker             const uint32_t blockIndex =
875*35238bceSAndroid Build Coastguard Worker                 gl.getProgramResourceIndex(program1.getProgram(), GL_SHADER_STORAGE_BLOCK, "Output");
876*35238bceSAndroid Build Coastguard Worker             const int blockSize = getProgramResourceInt(gl, program1.getProgram(), GL_SHADER_STORAGE_BLOCK, blockIndex,
877*35238bceSAndroid Build Coastguard Worker                                                         GL_BUFFER_DATA_SIZE);
878*35238bceSAndroid Build Coastguard Worker             const uint32_t valueIndex = gl.getProgramResourceIndex(program1.getProgram(), GL_BUFFER_VARIABLE, "sum");
879*35238bceSAndroid Build Coastguard Worker             const InterfaceVariableInfo valueInfo =
880*35238bceSAndroid Build Coastguard Worker                 getProgramInterfaceVariableInfo(gl, program1.getProgram(), GL_BUFFER_VARIABLE, valueIndex);
881*35238bceSAndroid Build Coastguard Worker             const BufferMemMap bufMap(gl, GL_SHADER_STORAGE_BUFFER, 0, blockSize, GL_MAP_READ_BIT);
882*35238bceSAndroid Build Coastguard Worker 
883*35238bceSAndroid Build Coastguard Worker             const uint32_t res = *((const uint32_t *)((const uint8_t *)bufMap.getPtr() + valueInfo.offset));
884*35238bceSAndroid Build Coastguard Worker             uint32_t ref       = 0;
885*35238bceSAndroid Build Coastguard Worker 
886*35238bceSAndroid Build Coastguard Worker             for (int ndx = 0; ndx < m_workSize[0] * m_workSize[1] * m_workSize[2]; ndx++)
887*35238bceSAndroid Build Coastguard Worker                 ref += baseValue + (uint32_t)ndx;
888*35238bceSAndroid Build Coastguard Worker 
889*35238bceSAndroid Build Coastguard Worker             if (res != ref)
890*35238bceSAndroid Build Coastguard Worker             {
891*35238bceSAndroid Build Coastguard Worker                 m_testCtx.getLog() << TestLog::Message << "ERROR: comparison failed, expected " << ref << ", got "
892*35238bceSAndroid Build Coastguard Worker                                    << res << TestLog::EndMessage;
893*35238bceSAndroid Build Coastguard Worker                 throw tcu::TestError("Comparison failed");
894*35238bceSAndroid Build Coastguard Worker             }
895*35238bceSAndroid Build Coastguard Worker         }
896*35238bceSAndroid Build Coastguard Worker 
897*35238bceSAndroid Build Coastguard Worker         m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
898*35238bceSAndroid Build Coastguard Worker         return STOP;
899*35238bceSAndroid Build Coastguard Worker     }
900*35238bceSAndroid Build Coastguard Worker 
901*35238bceSAndroid Build Coastguard Worker private:
902*35238bceSAndroid Build Coastguard Worker     const tcu::IVec3 m_workSize;
903*35238bceSAndroid Build Coastguard Worker };
904*35238bceSAndroid Build Coastguard Worker 
905*35238bceSAndroid Build Coastguard Worker class BasicSharedVarCase : public TestCase
906*35238bceSAndroid Build Coastguard Worker {
907*35238bceSAndroid Build Coastguard Worker public:
BasicSharedVarCase(Context & context,const char * name,const char * description,const tcu::IVec3 & localSize,const tcu::IVec3 & workSize)908*35238bceSAndroid Build Coastguard Worker     BasicSharedVarCase(Context &context, const char *name, const char *description, const tcu::IVec3 &localSize,
909*35238bceSAndroid Build Coastguard Worker                        const tcu::IVec3 &workSize)
910*35238bceSAndroid Build Coastguard Worker         : TestCase(context, name, description)
911*35238bceSAndroid Build Coastguard Worker         , m_localSize(localSize)
912*35238bceSAndroid Build Coastguard Worker         , m_workSize(workSize)
913*35238bceSAndroid Build Coastguard Worker     {
914*35238bceSAndroid Build Coastguard Worker     }
915*35238bceSAndroid Build Coastguard Worker 
iterate(void)916*35238bceSAndroid Build Coastguard Worker     IterateResult iterate(void)
917*35238bceSAndroid Build Coastguard Worker     {
918*35238bceSAndroid Build Coastguard Worker         const glw::Functions &gl = m_context.getRenderContext().getFunctions();
919*35238bceSAndroid Build Coastguard Worker         const Buffer outputBuffer(m_context.getRenderContext());
920*35238bceSAndroid Build Coastguard Worker         const int workGroupSize  = m_localSize[0] * m_localSize[1] * m_localSize[2];
921*35238bceSAndroid Build Coastguard Worker         const int workGroupCount = m_workSize[0] * m_workSize[1] * m_workSize[2];
922*35238bceSAndroid Build Coastguard Worker         const int numValues      = workGroupSize * workGroupCount;
923*35238bceSAndroid Build Coastguard Worker 
924*35238bceSAndroid Build Coastguard Worker         const GLSLVersion glslVersion = glu::getContextTypeGLSLVersion(m_context.getRenderContext().getType());
925*35238bceSAndroid Build Coastguard Worker         std::ostringstream src;
926*35238bceSAndroid Build Coastguard Worker 
927*35238bceSAndroid Build Coastguard Worker         src << getGLSLVersionDeclaration(glslVersion) << "\n"
928*35238bceSAndroid Build Coastguard Worker             << "layout (local_size_x = " << m_localSize[0] << ", local_size_y = " << m_localSize[1]
929*35238bceSAndroid Build Coastguard Worker             << ", local_size_z = " << m_localSize[2] << ") in;\n"
930*35238bceSAndroid Build Coastguard Worker             << "layout(binding = 0) buffer Output {\n"
931*35238bceSAndroid Build Coastguard Worker             << "    uint values[" << numValues << "];\n"
932*35238bceSAndroid Build Coastguard Worker             << "} sb_out;\n\n"
933*35238bceSAndroid Build Coastguard Worker             << "shared uint offsets[" << workGroupSize << "];\n\n"
934*35238bceSAndroid Build Coastguard Worker             << "void main (void) {\n"
935*35238bceSAndroid Build Coastguard Worker             << "    uint localSize  = gl_WorkGroupSize.x*gl_WorkGroupSize.y*gl_WorkGroupSize.z;\n"
936*35238bceSAndroid Build Coastguard Worker             << "    uint globalNdx  = gl_NumWorkGroups.x*gl_NumWorkGroups.y*gl_WorkGroupID.z + "
937*35238bceSAndroid Build Coastguard Worker                "gl_NumWorkGroups.x*gl_WorkGroupID.y + gl_WorkGroupID.x;\n"
938*35238bceSAndroid Build Coastguard Worker             << "    uint globalOffs = localSize*globalNdx;\n"
939*35238bceSAndroid Build Coastguard Worker             << "    uint localOffs  = gl_WorkGroupSize.x*gl_WorkGroupSize.y*gl_LocalInvocationID.z + "
940*35238bceSAndroid Build Coastguard Worker                "gl_WorkGroupSize.x*gl_LocalInvocationID.y + gl_LocalInvocationID.x;\n"
941*35238bceSAndroid Build Coastguard Worker             << "\n"
942*35238bceSAndroid Build Coastguard Worker             << "    offsets[localSize-localOffs-1u] = globalOffs + localOffs*localOffs;\n"
943*35238bceSAndroid Build Coastguard Worker             << "    barrier();\n"
944*35238bceSAndroid Build Coastguard Worker             << "    sb_out.values[globalOffs + localOffs] = offsets[localOffs];\n"
945*35238bceSAndroid Build Coastguard Worker             << "}\n";
946*35238bceSAndroid Build Coastguard Worker 
947*35238bceSAndroid Build Coastguard Worker         const ShaderProgram program(m_context.getRenderContext(), ProgramSources()
948*35238bceSAndroid Build Coastguard Worker                                                                       << ShaderSource(SHADERTYPE_COMPUTE, src.str()));
949*35238bceSAndroid Build Coastguard Worker 
950*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << program;
951*35238bceSAndroid Build Coastguard Worker         if (!program.isOk())
952*35238bceSAndroid Build Coastguard Worker             TCU_FAIL("Compile failed");
953*35238bceSAndroid Build Coastguard Worker 
954*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << TestLog::Message << "Work groups: " << m_workSize << TestLog::EndMessage;
955*35238bceSAndroid Build Coastguard Worker 
956*35238bceSAndroid Build Coastguard Worker         gl.useProgram(program.getProgram());
957*35238bceSAndroid Build Coastguard Worker 
958*35238bceSAndroid Build Coastguard Worker         // Output buffer setup
959*35238bceSAndroid Build Coastguard Worker         {
960*35238bceSAndroid Build Coastguard Worker             const uint32_t blockIndex =
961*35238bceSAndroid Build Coastguard Worker                 gl.getProgramResourceIndex(program.getProgram(), GL_SHADER_STORAGE_BLOCK, "Output");
962*35238bceSAndroid Build Coastguard Worker             const int blockSize = getProgramResourceInt(gl, program.getProgram(), GL_SHADER_STORAGE_BLOCK, blockIndex,
963*35238bceSAndroid Build Coastguard Worker                                                         GL_BUFFER_DATA_SIZE);
964*35238bceSAndroid Build Coastguard Worker 
965*35238bceSAndroid Build Coastguard Worker             gl.bindBuffer(GL_SHADER_STORAGE_BUFFER, *outputBuffer);
966*35238bceSAndroid Build Coastguard Worker             gl.bufferData(GL_SHADER_STORAGE_BUFFER, blockSize, DE_NULL, GL_STREAM_READ);
967*35238bceSAndroid Build Coastguard Worker             gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, *outputBuffer);
968*35238bceSAndroid Build Coastguard Worker             GLU_EXPECT_NO_ERROR(gl.getError(), "Output buffer setup failed");
969*35238bceSAndroid Build Coastguard Worker         }
970*35238bceSAndroid Build Coastguard Worker 
971*35238bceSAndroid Build Coastguard Worker         // Dispatch compute workload
972*35238bceSAndroid Build Coastguard Worker         gl.dispatchCompute(m_workSize[0], m_workSize[1], m_workSize[2]);
973*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(gl.getError(), "glDispatchCompute()");
974*35238bceSAndroid Build Coastguard Worker 
975*35238bceSAndroid Build Coastguard Worker         // Read back and compare
976*35238bceSAndroid Build Coastguard Worker         {
977*35238bceSAndroid Build Coastguard Worker             const uint32_t blockIndex =
978*35238bceSAndroid Build Coastguard Worker                 gl.getProgramResourceIndex(program.getProgram(), GL_SHADER_STORAGE_BLOCK, "Output");
979*35238bceSAndroid Build Coastguard Worker             const int blockSize = getProgramResourceInt(gl, program.getProgram(), GL_SHADER_STORAGE_BLOCK, blockIndex,
980*35238bceSAndroid Build Coastguard Worker                                                         GL_BUFFER_DATA_SIZE);
981*35238bceSAndroid Build Coastguard Worker             const uint32_t valueIndex =
982*35238bceSAndroid Build Coastguard Worker                 gl.getProgramResourceIndex(program.getProgram(), GL_BUFFER_VARIABLE, "Output.values");
983*35238bceSAndroid Build Coastguard Worker             const InterfaceVariableInfo valueInfo =
984*35238bceSAndroid Build Coastguard Worker                 getProgramInterfaceVariableInfo(gl, program.getProgram(), GL_BUFFER_VARIABLE, valueIndex);
985*35238bceSAndroid Build Coastguard Worker             const BufferMemMap bufMap(gl, GL_SHADER_STORAGE_BUFFER, 0, blockSize, GL_MAP_READ_BIT);
986*35238bceSAndroid Build Coastguard Worker 
987*35238bceSAndroid Build Coastguard Worker             for (int groupNdx = 0; groupNdx < workGroupCount; groupNdx++)
988*35238bceSAndroid Build Coastguard Worker             {
989*35238bceSAndroid Build Coastguard Worker                 for (int localOffs = 0; localOffs < workGroupSize; localOffs++)
990*35238bceSAndroid Build Coastguard Worker                 {
991*35238bceSAndroid Build Coastguard Worker                     const int globalOffs = groupNdx * workGroupSize;
992*35238bceSAndroid Build Coastguard Worker                     const uint32_t res   = *((const uint32_t *)((const uint8_t *)bufMap.getPtr() + valueInfo.offset +
993*35238bceSAndroid Build Coastguard Worker                                                               valueInfo.arrayStride * (globalOffs + localOffs)));
994*35238bceSAndroid Build Coastguard Worker                     const uint32_t ref =
995*35238bceSAndroid Build Coastguard Worker                         (uint32_t)(globalOffs + (workGroupSize - localOffs - 1) * (workGroupSize - localOffs - 1));
996*35238bceSAndroid Build Coastguard Worker 
997*35238bceSAndroid Build Coastguard Worker                     if (res != ref)
998*35238bceSAndroid Build Coastguard Worker                         throw tcu::TestError(string("Comparison failed for Output.values[") +
999*35238bceSAndroid Build Coastguard Worker                                              de::toString(globalOffs + localOffs) + "]");
1000*35238bceSAndroid Build Coastguard Worker                 }
1001*35238bceSAndroid Build Coastguard Worker             }
1002*35238bceSAndroid Build Coastguard Worker         }
1003*35238bceSAndroid Build Coastguard Worker 
1004*35238bceSAndroid Build Coastguard Worker         m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1005*35238bceSAndroid Build Coastguard Worker         return STOP;
1006*35238bceSAndroid Build Coastguard Worker     }
1007*35238bceSAndroid Build Coastguard Worker 
1008*35238bceSAndroid Build Coastguard Worker private:
1009*35238bceSAndroid Build Coastguard Worker     const tcu::IVec3 m_localSize;
1010*35238bceSAndroid Build Coastguard Worker     const tcu::IVec3 m_workSize;
1011*35238bceSAndroid Build Coastguard Worker };
1012*35238bceSAndroid Build Coastguard Worker 
1013*35238bceSAndroid Build Coastguard Worker class SharedVarAtomicOpCase : public TestCase
1014*35238bceSAndroid Build Coastguard Worker {
1015*35238bceSAndroid Build Coastguard Worker public:
SharedVarAtomicOpCase(Context & context,const char * name,const char * description,const tcu::IVec3 & localSize,const tcu::IVec3 & workSize)1016*35238bceSAndroid Build Coastguard Worker     SharedVarAtomicOpCase(Context &context, const char *name, const char *description, const tcu::IVec3 &localSize,
1017*35238bceSAndroid Build Coastguard Worker                           const tcu::IVec3 &workSize)
1018*35238bceSAndroid Build Coastguard Worker         : TestCase(context, name, description)
1019*35238bceSAndroid Build Coastguard Worker         , m_localSize(localSize)
1020*35238bceSAndroid Build Coastguard Worker         , m_workSize(workSize)
1021*35238bceSAndroid Build Coastguard Worker     {
1022*35238bceSAndroid Build Coastguard Worker     }
1023*35238bceSAndroid Build Coastguard Worker 
iterate(void)1024*35238bceSAndroid Build Coastguard Worker     IterateResult iterate(void)
1025*35238bceSAndroid Build Coastguard Worker     {
1026*35238bceSAndroid Build Coastguard Worker         const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1027*35238bceSAndroid Build Coastguard Worker         const Buffer outputBuffer(m_context.getRenderContext());
1028*35238bceSAndroid Build Coastguard Worker         const int workGroupSize  = m_localSize[0] * m_localSize[1] * m_localSize[2];
1029*35238bceSAndroid Build Coastguard Worker         const int workGroupCount = m_workSize[0] * m_workSize[1] * m_workSize[2];
1030*35238bceSAndroid Build Coastguard Worker         const int numValues      = workGroupSize * workGroupCount;
1031*35238bceSAndroid Build Coastguard Worker 
1032*35238bceSAndroid Build Coastguard Worker         const GLSLVersion glslVersion = glu::getContextTypeGLSLVersion(m_context.getRenderContext().getType());
1033*35238bceSAndroid Build Coastguard Worker         std::ostringstream src;
1034*35238bceSAndroid Build Coastguard Worker 
1035*35238bceSAndroid Build Coastguard Worker         src << getGLSLVersionDeclaration(glslVersion) << "\n"
1036*35238bceSAndroid Build Coastguard Worker             << "layout (local_size_x = " << m_localSize[0] << ", local_size_y = " << m_localSize[1]
1037*35238bceSAndroid Build Coastguard Worker             << ", local_size_z = " << m_localSize[2] << ") in;\n"
1038*35238bceSAndroid Build Coastguard Worker             << "layout(binding = 0) buffer Output {\n"
1039*35238bceSAndroid Build Coastguard Worker             << "    uint values[" << numValues << "];\n"
1040*35238bceSAndroid Build Coastguard Worker             << "} sb_out;\n\n"
1041*35238bceSAndroid Build Coastguard Worker             << "shared uint count;\n\n"
1042*35238bceSAndroid Build Coastguard Worker             << "void main (void) {\n"
1043*35238bceSAndroid Build Coastguard Worker             << "    uint localSize  = gl_WorkGroupSize.x*gl_WorkGroupSize.y*gl_WorkGroupSize.z;\n"
1044*35238bceSAndroid Build Coastguard Worker             << "    uint globalNdx  = gl_NumWorkGroups.x*gl_NumWorkGroups.y*gl_WorkGroupID.z + "
1045*35238bceSAndroid Build Coastguard Worker                "gl_NumWorkGroups.x*gl_WorkGroupID.y + gl_WorkGroupID.x;\n"
1046*35238bceSAndroid Build Coastguard Worker             << "    uint globalOffs = localSize*globalNdx;\n"
1047*35238bceSAndroid Build Coastguard Worker             << "\n"
1048*35238bceSAndroid Build Coastguard Worker             << "    count = 0u;\n"
1049*35238bceSAndroid Build Coastguard Worker             << "    barrier();\n"
1050*35238bceSAndroid Build Coastguard Worker             << "    uint oldVal = atomicAdd(count, 1u);\n"
1051*35238bceSAndroid Build Coastguard Worker             << "    sb_out.values[globalOffs+oldVal] = oldVal+1u;\n"
1052*35238bceSAndroid Build Coastguard Worker             << "}\n";
1053*35238bceSAndroid Build Coastguard Worker 
1054*35238bceSAndroid Build Coastguard Worker         const ShaderProgram program(m_context.getRenderContext(), ProgramSources()
1055*35238bceSAndroid Build Coastguard Worker                                                                       << ShaderSource(SHADERTYPE_COMPUTE, src.str()));
1056*35238bceSAndroid Build Coastguard Worker 
1057*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << program;
1058*35238bceSAndroid Build Coastguard Worker         if (!program.isOk())
1059*35238bceSAndroid Build Coastguard Worker             TCU_FAIL("Compile failed");
1060*35238bceSAndroid Build Coastguard Worker 
1061*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << TestLog::Message << "Work groups: " << m_workSize << TestLog::EndMessage;
1062*35238bceSAndroid Build Coastguard Worker 
1063*35238bceSAndroid Build Coastguard Worker         gl.useProgram(program.getProgram());
1064*35238bceSAndroid Build Coastguard Worker 
1065*35238bceSAndroid Build Coastguard Worker         // Output buffer setup
1066*35238bceSAndroid Build Coastguard Worker         {
1067*35238bceSAndroid Build Coastguard Worker             const uint32_t blockIndex =
1068*35238bceSAndroid Build Coastguard Worker                 gl.getProgramResourceIndex(program.getProgram(), GL_SHADER_STORAGE_BLOCK, "Output");
1069*35238bceSAndroid Build Coastguard Worker             const int blockSize = getProgramResourceInt(gl, program.getProgram(), GL_SHADER_STORAGE_BLOCK, blockIndex,
1070*35238bceSAndroid Build Coastguard Worker                                                         GL_BUFFER_DATA_SIZE);
1071*35238bceSAndroid Build Coastguard Worker 
1072*35238bceSAndroid Build Coastguard Worker             gl.bindBuffer(GL_SHADER_STORAGE_BUFFER, *outputBuffer);
1073*35238bceSAndroid Build Coastguard Worker             gl.bufferData(GL_SHADER_STORAGE_BUFFER, blockSize, DE_NULL, GL_STREAM_READ);
1074*35238bceSAndroid Build Coastguard Worker             gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, *outputBuffer);
1075*35238bceSAndroid Build Coastguard Worker             GLU_EXPECT_NO_ERROR(gl.getError(), "Output buffer setup failed");
1076*35238bceSAndroid Build Coastguard Worker         }
1077*35238bceSAndroid Build Coastguard Worker 
1078*35238bceSAndroid Build Coastguard Worker         // Dispatch compute workload
1079*35238bceSAndroid Build Coastguard Worker         gl.dispatchCompute(m_workSize[0], m_workSize[1], m_workSize[2]);
1080*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(gl.getError(), "glDispatchCompute()");
1081*35238bceSAndroid Build Coastguard Worker 
1082*35238bceSAndroid Build Coastguard Worker         // Read back and compare
1083*35238bceSAndroid Build Coastguard Worker         {
1084*35238bceSAndroid Build Coastguard Worker             const uint32_t blockIndex =
1085*35238bceSAndroid Build Coastguard Worker                 gl.getProgramResourceIndex(program.getProgram(), GL_SHADER_STORAGE_BLOCK, "Output");
1086*35238bceSAndroid Build Coastguard Worker             const int blockSize = getProgramResourceInt(gl, program.getProgram(), GL_SHADER_STORAGE_BLOCK, blockIndex,
1087*35238bceSAndroid Build Coastguard Worker                                                         GL_BUFFER_DATA_SIZE);
1088*35238bceSAndroid Build Coastguard Worker             const uint32_t valueIndex =
1089*35238bceSAndroid Build Coastguard Worker                 gl.getProgramResourceIndex(program.getProgram(), GL_BUFFER_VARIABLE, "Output.values");
1090*35238bceSAndroid Build Coastguard Worker             const InterfaceVariableInfo valueInfo =
1091*35238bceSAndroid Build Coastguard Worker                 getProgramInterfaceVariableInfo(gl, program.getProgram(), GL_BUFFER_VARIABLE, valueIndex);
1092*35238bceSAndroid Build Coastguard Worker             const BufferMemMap bufMap(gl, GL_SHADER_STORAGE_BUFFER, 0, blockSize, GL_MAP_READ_BIT);
1093*35238bceSAndroid Build Coastguard Worker 
1094*35238bceSAndroid Build Coastguard Worker             for (int groupNdx = 0; groupNdx < workGroupCount; groupNdx++)
1095*35238bceSAndroid Build Coastguard Worker             {
1096*35238bceSAndroid Build Coastguard Worker                 for (int localOffs = 0; localOffs < workGroupSize; localOffs++)
1097*35238bceSAndroid Build Coastguard Worker                 {
1098*35238bceSAndroid Build Coastguard Worker                     const int globalOffs = groupNdx * workGroupSize;
1099*35238bceSAndroid Build Coastguard Worker                     const uint32_t res   = *((const uint32_t *)((const uint8_t *)bufMap.getPtr() + valueInfo.offset +
1100*35238bceSAndroid Build Coastguard Worker                                                               valueInfo.arrayStride * (globalOffs + localOffs)));
1101*35238bceSAndroid Build Coastguard Worker                     const uint32_t ref   = (uint32_t)(localOffs + 1);
1102*35238bceSAndroid Build Coastguard Worker 
1103*35238bceSAndroid Build Coastguard Worker                     if (res != ref)
1104*35238bceSAndroid Build Coastguard Worker                         throw tcu::TestError(string("Comparison failed for Output.values[") +
1105*35238bceSAndroid Build Coastguard Worker                                              de::toString(globalOffs + localOffs) + "]");
1106*35238bceSAndroid Build Coastguard Worker                 }
1107*35238bceSAndroid Build Coastguard Worker             }
1108*35238bceSAndroid Build Coastguard Worker         }
1109*35238bceSAndroid Build Coastguard Worker 
1110*35238bceSAndroid Build Coastguard Worker         m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1111*35238bceSAndroid Build Coastguard Worker         return STOP;
1112*35238bceSAndroid Build Coastguard Worker     }
1113*35238bceSAndroid Build Coastguard Worker 
1114*35238bceSAndroid Build Coastguard Worker private:
1115*35238bceSAndroid Build Coastguard Worker     const tcu::IVec3 m_localSize;
1116*35238bceSAndroid Build Coastguard Worker     const tcu::IVec3 m_workSize;
1117*35238bceSAndroid Build Coastguard Worker };
1118*35238bceSAndroid Build Coastguard Worker 
1119*35238bceSAndroid Build Coastguard Worker class CopyImageToSSBOCase : public TestCase
1120*35238bceSAndroid Build Coastguard Worker {
1121*35238bceSAndroid Build Coastguard Worker public:
CopyImageToSSBOCase(Context & context,const char * name,const char * description,const tcu::IVec2 & localSize,const tcu::IVec2 & imageSize)1122*35238bceSAndroid Build Coastguard Worker     CopyImageToSSBOCase(Context &context, const char *name, const char *description, const tcu::IVec2 &localSize,
1123*35238bceSAndroid Build Coastguard Worker                         const tcu::IVec2 &imageSize)
1124*35238bceSAndroid Build Coastguard Worker         : TestCase(context, name, description)
1125*35238bceSAndroid Build Coastguard Worker         , m_localSize(localSize)
1126*35238bceSAndroid Build Coastguard Worker         , m_imageSize(imageSize)
1127*35238bceSAndroid Build Coastguard Worker     {
1128*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(m_imageSize[0] % m_localSize[0] == 0);
1129*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(m_imageSize[1] % m_localSize[1] == 0);
1130*35238bceSAndroid Build Coastguard Worker     }
1131*35238bceSAndroid Build Coastguard Worker 
iterate(void)1132*35238bceSAndroid Build Coastguard Worker     IterateResult iterate(void)
1133*35238bceSAndroid Build Coastguard Worker     {
1134*35238bceSAndroid Build Coastguard Worker         const GLSLVersion glslVersion = glu::getContextTypeGLSLVersion(m_context.getRenderContext().getType());
1135*35238bceSAndroid Build Coastguard Worker         std::ostringstream src;
1136*35238bceSAndroid Build Coastguard Worker 
1137*35238bceSAndroid Build Coastguard Worker         src << getGLSLVersionDeclaration(glslVersion) << "\n"
1138*35238bceSAndroid Build Coastguard Worker             << "layout (local_size_x = " << m_localSize[0] << ", local_size_y = " << m_localSize[1] << ") in;\n"
1139*35238bceSAndroid Build Coastguard Worker             << "layout(r32ui, binding = 1) readonly uniform highp uimage2D u_srcImg;\n"
1140*35238bceSAndroid Build Coastguard Worker             << "layout(binding = 0) buffer Output {\n"
1141*35238bceSAndroid Build Coastguard Worker             << "    uint values[" << (m_imageSize[0] * m_imageSize[1]) << "];\n"
1142*35238bceSAndroid Build Coastguard Worker             << "} sb_out;\n\n"
1143*35238bceSAndroid Build Coastguard Worker             << "void main (void) {\n"
1144*35238bceSAndroid Build Coastguard Worker             << "    uint stride = gl_NumWorkGroups.x*gl_WorkGroupSize.x;\n"
1145*35238bceSAndroid Build Coastguard Worker             << "    uint value  = imageLoad(u_srcImg, ivec2(gl_GlobalInvocationID.xy)).x;\n"
1146*35238bceSAndroid Build Coastguard Worker             << "    sb_out.values[gl_GlobalInvocationID.y*stride + gl_GlobalInvocationID.x] = value;\n"
1147*35238bceSAndroid Build Coastguard Worker             << "}\n";
1148*35238bceSAndroid Build Coastguard Worker 
1149*35238bceSAndroid Build Coastguard Worker         const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1150*35238bceSAndroid Build Coastguard Worker         const Buffer outputBuffer(m_context.getRenderContext());
1151*35238bceSAndroid Build Coastguard Worker         const Texture inputTexture(m_context.getRenderContext());
1152*35238bceSAndroid Build Coastguard Worker         const ShaderProgram program(m_context.getRenderContext(), ProgramSources()
1153*35238bceSAndroid Build Coastguard Worker                                                                       << ShaderSource(SHADERTYPE_COMPUTE, src.str()));
1154*35238bceSAndroid Build Coastguard Worker         const tcu::IVec2 workSize = m_imageSize / m_localSize;
1155*35238bceSAndroid Build Coastguard Worker         de::Random rnd(0xab2c7);
1156*35238bceSAndroid Build Coastguard Worker         vector<uint32_t> inputValues(m_imageSize[0] * m_imageSize[1]);
1157*35238bceSAndroid Build Coastguard Worker 
1158*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << program;
1159*35238bceSAndroid Build Coastguard Worker         if (!program.isOk())
1160*35238bceSAndroid Build Coastguard Worker             TCU_FAIL("Compile failed");
1161*35238bceSAndroid Build Coastguard Worker 
1162*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << TestLog::Message << "Work groups: " << workSize << TestLog::EndMessage;
1163*35238bceSAndroid Build Coastguard Worker 
1164*35238bceSAndroid Build Coastguard Worker         gl.useProgram(program.getProgram());
1165*35238bceSAndroid Build Coastguard Worker 
1166*35238bceSAndroid Build Coastguard Worker         // Input values
1167*35238bceSAndroid Build Coastguard Worker         for (vector<uint32_t>::iterator i = inputValues.begin(); i != inputValues.end(); ++i)
1168*35238bceSAndroid Build Coastguard Worker             *i = rnd.getUint32();
1169*35238bceSAndroid Build Coastguard Worker 
1170*35238bceSAndroid Build Coastguard Worker         // Input image setup
1171*35238bceSAndroid Build Coastguard Worker         gl.bindTexture(GL_TEXTURE_2D, *inputTexture);
1172*35238bceSAndroid Build Coastguard Worker         gl.texStorage2D(GL_TEXTURE_2D, 1, GL_R32UI, m_imageSize[0], m_imageSize[1]);
1173*35238bceSAndroid Build Coastguard Worker         gl.texSubImage2D(GL_TEXTURE_2D, 0, 0, 0, m_imageSize[0], m_imageSize[1], GL_RED_INTEGER, GL_UNSIGNED_INT,
1174*35238bceSAndroid Build Coastguard Worker                          &inputValues[0]);
1175*35238bceSAndroid Build Coastguard Worker         gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1176*35238bceSAndroid Build Coastguard Worker         gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1177*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(gl.getError(), "Uploading image data failed");
1178*35238bceSAndroid Build Coastguard Worker 
1179*35238bceSAndroid Build Coastguard Worker         // Bind to unit 1
1180*35238bceSAndroid Build Coastguard Worker         gl.bindImageTexture(1, *inputTexture, 0, GL_FALSE, 0, GL_READ_ONLY, GL_R32UI);
1181*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(gl.getError(), "Image setup failed");
1182*35238bceSAndroid Build Coastguard Worker 
1183*35238bceSAndroid Build Coastguard Worker         // Output buffer setup
1184*35238bceSAndroid Build Coastguard Worker         {
1185*35238bceSAndroid Build Coastguard Worker             const uint32_t blockIndex =
1186*35238bceSAndroid Build Coastguard Worker                 gl.getProgramResourceIndex(program.getProgram(), GL_SHADER_STORAGE_BLOCK, "Output");
1187*35238bceSAndroid Build Coastguard Worker             const int blockSize = getProgramResourceInt(gl, program.getProgram(), GL_SHADER_STORAGE_BLOCK, blockIndex,
1188*35238bceSAndroid Build Coastguard Worker                                                         GL_BUFFER_DATA_SIZE);
1189*35238bceSAndroid Build Coastguard Worker 
1190*35238bceSAndroid Build Coastguard Worker             gl.bindBuffer(GL_SHADER_STORAGE_BUFFER, *outputBuffer);
1191*35238bceSAndroid Build Coastguard Worker             gl.bufferData(GL_SHADER_STORAGE_BUFFER, blockSize, DE_NULL, GL_STREAM_READ);
1192*35238bceSAndroid Build Coastguard Worker             gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, *outputBuffer);
1193*35238bceSAndroid Build Coastguard Worker             GLU_EXPECT_NO_ERROR(gl.getError(), "Output buffer setup failed");
1194*35238bceSAndroid Build Coastguard Worker         }
1195*35238bceSAndroid Build Coastguard Worker 
1196*35238bceSAndroid Build Coastguard Worker         // Dispatch compute workload
1197*35238bceSAndroid Build Coastguard Worker         gl.dispatchCompute(workSize[0], workSize[1], 1);
1198*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(gl.getError(), "glDispatchCompute()");
1199*35238bceSAndroid Build Coastguard Worker 
1200*35238bceSAndroid Build Coastguard Worker         // Read back and compare
1201*35238bceSAndroid Build Coastguard Worker         {
1202*35238bceSAndroid Build Coastguard Worker             const uint32_t blockIndex =
1203*35238bceSAndroid Build Coastguard Worker                 gl.getProgramResourceIndex(program.getProgram(), GL_SHADER_STORAGE_BLOCK, "Output");
1204*35238bceSAndroid Build Coastguard Worker             const int blockSize = getProgramResourceInt(gl, program.getProgram(), GL_SHADER_STORAGE_BLOCK, blockIndex,
1205*35238bceSAndroid Build Coastguard Worker                                                         GL_BUFFER_DATA_SIZE);
1206*35238bceSAndroid Build Coastguard Worker             const uint32_t valueIndex =
1207*35238bceSAndroid Build Coastguard Worker                 gl.getProgramResourceIndex(program.getProgram(), GL_BUFFER_VARIABLE, "Output.values");
1208*35238bceSAndroid Build Coastguard Worker             const InterfaceVariableInfo valueInfo =
1209*35238bceSAndroid Build Coastguard Worker                 getProgramInterfaceVariableInfo(gl, program.getProgram(), GL_BUFFER_VARIABLE, valueIndex);
1210*35238bceSAndroid Build Coastguard Worker             const BufferMemMap bufMap(gl, GL_SHADER_STORAGE_BUFFER, 0, blockSize, GL_MAP_READ_BIT);
1211*35238bceSAndroid Build Coastguard Worker 
1212*35238bceSAndroid Build Coastguard Worker             TCU_CHECK(valueInfo.arraySize == (uint32_t)inputValues.size());
1213*35238bceSAndroid Build Coastguard Worker 
1214*35238bceSAndroid Build Coastguard Worker             for (uint32_t ndx = 0; ndx < valueInfo.arraySize; ndx++)
1215*35238bceSAndroid Build Coastguard Worker             {
1216*35238bceSAndroid Build Coastguard Worker                 const uint32_t res = *((const uint32_t *)((const uint8_t *)bufMap.getPtr() + valueInfo.offset +
1217*35238bceSAndroid Build Coastguard Worker                                                           valueInfo.arrayStride * ndx));
1218*35238bceSAndroid Build Coastguard Worker                 const uint32_t ref = inputValues[ndx];
1219*35238bceSAndroid Build Coastguard Worker 
1220*35238bceSAndroid Build Coastguard Worker                 if (res != ref)
1221*35238bceSAndroid Build Coastguard Worker                     throw tcu::TestError(string("Comparison failed for Output.values[") + de::toString(ndx) + "]");
1222*35238bceSAndroid Build Coastguard Worker             }
1223*35238bceSAndroid Build Coastguard Worker         }
1224*35238bceSAndroid Build Coastguard Worker 
1225*35238bceSAndroid Build Coastguard Worker         m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1226*35238bceSAndroid Build Coastguard Worker         return STOP;
1227*35238bceSAndroid Build Coastguard Worker     }
1228*35238bceSAndroid Build Coastguard Worker 
1229*35238bceSAndroid Build Coastguard Worker private:
1230*35238bceSAndroid Build Coastguard Worker     const tcu::IVec2 m_localSize;
1231*35238bceSAndroid Build Coastguard Worker     const tcu::IVec2 m_imageSize;
1232*35238bceSAndroid Build Coastguard Worker };
1233*35238bceSAndroid Build Coastguard Worker 
1234*35238bceSAndroid Build Coastguard Worker class CopySSBOToImageCase : public TestCase
1235*35238bceSAndroid Build Coastguard Worker {
1236*35238bceSAndroid Build Coastguard Worker public:
CopySSBOToImageCase(Context & context,const char * name,const char * description,const tcu::IVec2 & localSize,const tcu::IVec2 & imageSize)1237*35238bceSAndroid Build Coastguard Worker     CopySSBOToImageCase(Context &context, const char *name, const char *description, const tcu::IVec2 &localSize,
1238*35238bceSAndroid Build Coastguard Worker                         const tcu::IVec2 &imageSize)
1239*35238bceSAndroid Build Coastguard Worker         : TestCase(context, name, description)
1240*35238bceSAndroid Build Coastguard Worker         , m_localSize(localSize)
1241*35238bceSAndroid Build Coastguard Worker         , m_imageSize(imageSize)
1242*35238bceSAndroid Build Coastguard Worker     {
1243*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(m_imageSize[0] % m_localSize[0] == 0);
1244*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(m_imageSize[1] % m_localSize[1] == 0);
1245*35238bceSAndroid Build Coastguard Worker     }
1246*35238bceSAndroid Build Coastguard Worker 
iterate(void)1247*35238bceSAndroid Build Coastguard Worker     IterateResult iterate(void)
1248*35238bceSAndroid Build Coastguard Worker     {
1249*35238bceSAndroid Build Coastguard Worker         const GLSLVersion glslVersion = glu::getContextTypeGLSLVersion(m_context.getRenderContext().getType());
1250*35238bceSAndroid Build Coastguard Worker         std::ostringstream src;
1251*35238bceSAndroid Build Coastguard Worker 
1252*35238bceSAndroid Build Coastguard Worker         src << getGLSLVersionDeclaration(glslVersion) << "\n"
1253*35238bceSAndroid Build Coastguard Worker             << "layout (local_size_x = " << m_localSize[0] << ", local_size_y = " << m_localSize[1] << ") in;\n"
1254*35238bceSAndroid Build Coastguard Worker             << "layout(r32ui, binding = 1) writeonly uniform highp uimage2D u_dstImg;\n"
1255*35238bceSAndroid Build Coastguard Worker             << "buffer Input {\n"
1256*35238bceSAndroid Build Coastguard Worker             << "    uint values[" << (m_imageSize[0] * m_imageSize[1]) << "];\n"
1257*35238bceSAndroid Build Coastguard Worker             << "} sb_in;\n\n"
1258*35238bceSAndroid Build Coastguard Worker             << "void main (void) {\n"
1259*35238bceSAndroid Build Coastguard Worker             << "    uint stride = gl_NumWorkGroups.x*gl_WorkGroupSize.x;\n"
1260*35238bceSAndroid Build Coastguard Worker             << "    uint value  = sb_in.values[gl_GlobalInvocationID.y*stride + gl_GlobalInvocationID.x];\n"
1261*35238bceSAndroid Build Coastguard Worker             << "    imageStore(u_dstImg, ivec2(gl_GlobalInvocationID.xy), uvec4(value, 0, 0, 0));\n"
1262*35238bceSAndroid Build Coastguard Worker             << "}\n";
1263*35238bceSAndroid Build Coastguard Worker 
1264*35238bceSAndroid Build Coastguard Worker         const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1265*35238bceSAndroid Build Coastguard Worker         const Buffer inputBuffer(m_context.getRenderContext());
1266*35238bceSAndroid Build Coastguard Worker         const Texture outputTexture(m_context.getRenderContext());
1267*35238bceSAndroid Build Coastguard Worker         const ShaderProgram program(m_context.getRenderContext(), ProgramSources()
1268*35238bceSAndroid Build Coastguard Worker                                                                       << ShaderSource(SHADERTYPE_COMPUTE, src.str()));
1269*35238bceSAndroid Build Coastguard Worker         const tcu::IVec2 workSize = m_imageSize / m_localSize;
1270*35238bceSAndroid Build Coastguard Worker         de::Random rnd(0x77238ac2);
1271*35238bceSAndroid Build Coastguard Worker         vector<uint32_t> inputValues(m_imageSize[0] * m_imageSize[1]);
1272*35238bceSAndroid Build Coastguard Worker 
1273*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << program;
1274*35238bceSAndroid Build Coastguard Worker         if (!program.isOk())
1275*35238bceSAndroid Build Coastguard Worker             TCU_FAIL("Compile failed");
1276*35238bceSAndroid Build Coastguard Worker 
1277*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << TestLog::Message << "Work groups: " << workSize << TestLog::EndMessage;
1278*35238bceSAndroid Build Coastguard Worker 
1279*35238bceSAndroid Build Coastguard Worker         gl.useProgram(program.getProgram());
1280*35238bceSAndroid Build Coastguard Worker 
1281*35238bceSAndroid Build Coastguard Worker         // Input values
1282*35238bceSAndroid Build Coastguard Worker         for (vector<uint32_t>::iterator i = inputValues.begin(); i != inputValues.end(); ++i)
1283*35238bceSAndroid Build Coastguard Worker             *i = rnd.getUint32();
1284*35238bceSAndroid Build Coastguard Worker 
1285*35238bceSAndroid Build Coastguard Worker         // Input buffer setup
1286*35238bceSAndroid Build Coastguard Worker         {
1287*35238bceSAndroid Build Coastguard Worker             const uint32_t blockIndex =
1288*35238bceSAndroid Build Coastguard Worker                 gl.getProgramResourceIndex(program.getProgram(), GL_SHADER_STORAGE_BLOCK, "Input");
1289*35238bceSAndroid Build Coastguard Worker             const InterfaceBlockInfo blockInfo =
1290*35238bceSAndroid Build Coastguard Worker                 getProgramInterfaceBlockInfo(gl, program.getProgram(), GL_SHADER_STORAGE_BLOCK, blockIndex);
1291*35238bceSAndroid Build Coastguard Worker             const uint32_t valueIndex =
1292*35238bceSAndroid Build Coastguard Worker                 gl.getProgramResourceIndex(program.getProgram(), GL_BUFFER_VARIABLE, "Input.values");
1293*35238bceSAndroid Build Coastguard Worker             const InterfaceVariableInfo valueInfo =
1294*35238bceSAndroid Build Coastguard Worker                 getProgramInterfaceVariableInfo(gl, program.getProgram(), GL_BUFFER_VARIABLE, valueIndex);
1295*35238bceSAndroid Build Coastguard Worker 
1296*35238bceSAndroid Build Coastguard Worker             gl.bindBuffer(GL_SHADER_STORAGE_BUFFER, *inputBuffer);
1297*35238bceSAndroid Build Coastguard Worker             gl.bufferData(GL_SHADER_STORAGE_BUFFER, (glw::GLsizeiptr)blockInfo.dataSize, DE_NULL, GL_STATIC_DRAW);
1298*35238bceSAndroid Build Coastguard Worker 
1299*35238bceSAndroid Build Coastguard Worker             TCU_CHECK(valueInfo.arraySize == (uint32_t)inputValues.size());
1300*35238bceSAndroid Build Coastguard Worker 
1301*35238bceSAndroid Build Coastguard Worker             {
1302*35238bceSAndroid Build Coastguard Worker                 const BufferMemMap bufMap(gl, GL_SHADER_STORAGE_BUFFER, 0, (int)blockInfo.dataSize, GL_MAP_WRITE_BIT);
1303*35238bceSAndroid Build Coastguard Worker 
1304*35238bceSAndroid Build Coastguard Worker                 for (uint32_t ndx = 0; ndx < (uint32_t)inputValues.size(); ndx++)
1305*35238bceSAndroid Build Coastguard Worker                     *(uint32_t *)((uint8_t *)bufMap.getPtr() + valueInfo.offset + ndx * valueInfo.arrayStride) =
1306*35238bceSAndroid Build Coastguard Worker                         inputValues[ndx];
1307*35238bceSAndroid Build Coastguard Worker             }
1308*35238bceSAndroid Build Coastguard Worker 
1309*35238bceSAndroid Build Coastguard Worker             gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, blockInfo.bufferBinding, *inputBuffer);
1310*35238bceSAndroid Build Coastguard Worker             GLU_EXPECT_NO_ERROR(gl.getError(), "Input buffer setup failed");
1311*35238bceSAndroid Build Coastguard Worker         }
1312*35238bceSAndroid Build Coastguard Worker 
1313*35238bceSAndroid Build Coastguard Worker         // Output image setup
1314*35238bceSAndroid Build Coastguard Worker         gl.bindTexture(GL_TEXTURE_2D, *outputTexture);
1315*35238bceSAndroid Build Coastguard Worker         gl.texStorage2D(GL_TEXTURE_2D, 1, GL_R32UI, m_imageSize[0], m_imageSize[1]);
1316*35238bceSAndroid Build Coastguard Worker         gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1317*35238bceSAndroid Build Coastguard Worker         gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1318*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(gl.getError(), "Uploading image data failed");
1319*35238bceSAndroid Build Coastguard Worker 
1320*35238bceSAndroid Build Coastguard Worker         // Bind to unit 1
1321*35238bceSAndroid Build Coastguard Worker         gl.bindImageTexture(1, *outputTexture, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_R32UI);
1322*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(gl.getError(), "Image setup failed");
1323*35238bceSAndroid Build Coastguard Worker 
1324*35238bceSAndroid Build Coastguard Worker         // Dispatch compute workload
1325*35238bceSAndroid Build Coastguard Worker         gl.dispatchCompute(workSize[0], workSize[1], 1);
1326*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(gl.getError(), "glDispatchCompute()");
1327*35238bceSAndroid Build Coastguard Worker 
1328*35238bceSAndroid Build Coastguard Worker         // Read back and compare
1329*35238bceSAndroid Build Coastguard Worker         {
1330*35238bceSAndroid Build Coastguard Worker             Framebuffer fbo(m_context.getRenderContext());
1331*35238bceSAndroid Build Coastguard Worker             vector<uint32_t> pixels(inputValues.size() * 4);
1332*35238bceSAndroid Build Coastguard Worker 
1333*35238bceSAndroid Build Coastguard Worker             gl.bindFramebuffer(GL_FRAMEBUFFER, *fbo);
1334*35238bceSAndroid Build Coastguard Worker             gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, *outputTexture, 0);
1335*35238bceSAndroid Build Coastguard Worker             TCU_CHECK(gl.checkFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
1336*35238bceSAndroid Build Coastguard Worker 
1337*35238bceSAndroid Build Coastguard Worker             // \note In ES3 we have to use GL_RGBA_INTEGER
1338*35238bceSAndroid Build Coastguard Worker             gl.readBuffer(GL_COLOR_ATTACHMENT0);
1339*35238bceSAndroid Build Coastguard Worker             gl.readPixels(0, 0, m_imageSize[0], m_imageSize[1], GL_RGBA_INTEGER, GL_UNSIGNED_INT, &pixels[0]);
1340*35238bceSAndroid Build Coastguard Worker             GLU_EXPECT_NO_ERROR(gl.getError(), "Reading pixels failed");
1341*35238bceSAndroid Build Coastguard Worker 
1342*35238bceSAndroid Build Coastguard Worker             for (uint32_t ndx = 0; ndx < (uint32_t)inputValues.size(); ndx++)
1343*35238bceSAndroid Build Coastguard Worker             {
1344*35238bceSAndroid Build Coastguard Worker                 const uint32_t res = pixels[ndx * 4];
1345*35238bceSAndroid Build Coastguard Worker                 const uint32_t ref = inputValues[ndx];
1346*35238bceSAndroid Build Coastguard Worker 
1347*35238bceSAndroid Build Coastguard Worker                 if (res != ref)
1348*35238bceSAndroid Build Coastguard Worker                     throw tcu::TestError(string("Comparison failed for pixel ") + de::toString(ndx));
1349*35238bceSAndroid Build Coastguard Worker             }
1350*35238bceSAndroid Build Coastguard Worker         }
1351*35238bceSAndroid Build Coastguard Worker 
1352*35238bceSAndroid Build Coastguard Worker         m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1353*35238bceSAndroid Build Coastguard Worker         return STOP;
1354*35238bceSAndroid Build Coastguard Worker     }
1355*35238bceSAndroid Build Coastguard Worker 
1356*35238bceSAndroid Build Coastguard Worker private:
1357*35238bceSAndroid Build Coastguard Worker     const tcu::IVec2 m_localSize;
1358*35238bceSAndroid Build Coastguard Worker     const tcu::IVec2 m_imageSize;
1359*35238bceSAndroid Build Coastguard Worker };
1360*35238bceSAndroid Build Coastguard Worker 
1361*35238bceSAndroid Build Coastguard Worker class ImageAtomicOpCase : public TestCase
1362*35238bceSAndroid Build Coastguard Worker {
1363*35238bceSAndroid Build Coastguard Worker public:
ImageAtomicOpCase(Context & context,const char * name,const char * description,int localSize,const tcu::IVec2 & imageSize)1364*35238bceSAndroid Build Coastguard Worker     ImageAtomicOpCase(Context &context, const char *name, const char *description, int localSize,
1365*35238bceSAndroid Build Coastguard Worker                       const tcu::IVec2 &imageSize)
1366*35238bceSAndroid Build Coastguard Worker         : TestCase(context, name, description)
1367*35238bceSAndroid Build Coastguard Worker         , m_localSize(localSize)
1368*35238bceSAndroid Build Coastguard Worker         , m_imageSize(imageSize)
1369*35238bceSAndroid Build Coastguard Worker     {
1370*35238bceSAndroid Build Coastguard Worker     }
1371*35238bceSAndroid Build Coastguard Worker 
init(void)1372*35238bceSAndroid Build Coastguard Worker     void init(void)
1373*35238bceSAndroid Build Coastguard Worker     {
1374*35238bceSAndroid Build Coastguard Worker         auto contextType = m_context.getRenderContext().getType();
1375*35238bceSAndroid Build Coastguard Worker         if (!glu::contextSupports(contextType, glu::ApiType::es(3, 2)) &&
1376*35238bceSAndroid Build Coastguard Worker             !glu::contextSupports(contextType, glu::ApiType::core(4, 5)) &&
1377*35238bceSAndroid Build Coastguard Worker             !m_context.getContextInfo().isExtensionSupported("GL_OES_shader_image_atomic"))
1378*35238bceSAndroid Build Coastguard Worker             TCU_THROW(NotSupportedError, "Test requires OES_shader_image_atomic extension");
1379*35238bceSAndroid Build Coastguard Worker     }
1380*35238bceSAndroid Build Coastguard Worker 
iterate(void)1381*35238bceSAndroid Build Coastguard Worker     IterateResult iterate(void)
1382*35238bceSAndroid Build Coastguard Worker     {
1383*35238bceSAndroid Build Coastguard Worker         glu::ContextType contextType  = m_context.getRenderContext().getType();
1384*35238bceSAndroid Build Coastguard Worker         const GLSLVersion glslVersion = glu::getContextTypeGLSLVersion(contextType);
1385*35238bceSAndroid Build Coastguard Worker         const bool supportsES32orGL45 = glu::contextSupports(contextType, glu::ApiType::es(3, 2)) ||
1386*35238bceSAndroid Build Coastguard Worker                                         glu::contextSupports(contextType, glu::ApiType::core(4, 5));
1387*35238bceSAndroid Build Coastguard Worker         std::ostringstream src;
1388*35238bceSAndroid Build Coastguard Worker 
1389*35238bceSAndroid Build Coastguard Worker         src << getGLSLVersionDeclaration(glslVersion) << "\n"
1390*35238bceSAndroid Build Coastguard Worker             << (supportsES32orGL45 ? "\n" : "#extension GL_OES_shader_image_atomic : require\n")
1391*35238bceSAndroid Build Coastguard Worker             << "layout (local_size_x = " << m_localSize << ") in;\n"
1392*35238bceSAndroid Build Coastguard Worker             << "layout(r32ui, binding = 1) uniform highp uimage2D u_dstImg;\n"
1393*35238bceSAndroid Build Coastguard Worker             << "buffer Input {\n"
1394*35238bceSAndroid Build Coastguard Worker             << "    uint values[" << (m_imageSize[0] * m_imageSize[1] * m_localSize) << "];\n"
1395*35238bceSAndroid Build Coastguard Worker             << "} sb_in;\n\n"
1396*35238bceSAndroid Build Coastguard Worker             << "void main (void) {\n"
1397*35238bceSAndroid Build Coastguard Worker             << "    uint stride = gl_NumWorkGroups.x*gl_WorkGroupSize.x;\n"
1398*35238bceSAndroid Build Coastguard Worker             << "    uint value  = sb_in.values[gl_GlobalInvocationID.y*stride + gl_GlobalInvocationID.x];\n"
1399*35238bceSAndroid Build Coastguard Worker             << "\n"
1400*35238bceSAndroid Build Coastguard Worker             << "    if (gl_LocalInvocationIndex == 0u)\n"
1401*35238bceSAndroid Build Coastguard Worker             << "        imageStore(u_dstImg, ivec2(gl_WorkGroupID.xy), uvec4(0));\n"
1402*35238bceSAndroid Build Coastguard Worker             << "    barrier();\n"
1403*35238bceSAndroid Build Coastguard Worker             << "    imageAtomicAdd(u_dstImg, ivec2(gl_WorkGroupID.xy), value);\n"
1404*35238bceSAndroid Build Coastguard Worker             << "}\n";
1405*35238bceSAndroid Build Coastguard Worker 
1406*35238bceSAndroid Build Coastguard Worker         const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1407*35238bceSAndroid Build Coastguard Worker         const Buffer inputBuffer(m_context.getRenderContext());
1408*35238bceSAndroid Build Coastguard Worker         const Texture outputTexture(m_context.getRenderContext());
1409*35238bceSAndroid Build Coastguard Worker         const ShaderProgram program(m_context.getRenderContext(), ProgramSources()
1410*35238bceSAndroid Build Coastguard Worker                                                                       << ShaderSource(SHADERTYPE_COMPUTE, src.str()));
1411*35238bceSAndroid Build Coastguard Worker         de::Random rnd(0x77238ac2);
1412*35238bceSAndroid Build Coastguard Worker         vector<uint32_t> inputValues(m_imageSize[0] * m_imageSize[1] * m_localSize);
1413*35238bceSAndroid Build Coastguard Worker 
1414*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << program;
1415*35238bceSAndroid Build Coastguard Worker         if (!program.isOk())
1416*35238bceSAndroid Build Coastguard Worker             TCU_FAIL("Compile failed");
1417*35238bceSAndroid Build Coastguard Worker 
1418*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << TestLog::Message << "Work groups: " << m_imageSize << TestLog::EndMessage;
1419*35238bceSAndroid Build Coastguard Worker 
1420*35238bceSAndroid Build Coastguard Worker         gl.useProgram(program.getProgram());
1421*35238bceSAndroid Build Coastguard Worker 
1422*35238bceSAndroid Build Coastguard Worker         // Input values
1423*35238bceSAndroid Build Coastguard Worker         for (vector<uint32_t>::iterator i = inputValues.begin(); i != inputValues.end(); ++i)
1424*35238bceSAndroid Build Coastguard Worker             *i = rnd.getUint32();
1425*35238bceSAndroid Build Coastguard Worker 
1426*35238bceSAndroid Build Coastguard Worker         // Input buffer setup
1427*35238bceSAndroid Build Coastguard Worker         {
1428*35238bceSAndroid Build Coastguard Worker             const uint32_t blockIndex =
1429*35238bceSAndroid Build Coastguard Worker                 gl.getProgramResourceIndex(program.getProgram(), GL_SHADER_STORAGE_BLOCK, "Input");
1430*35238bceSAndroid Build Coastguard Worker             const InterfaceBlockInfo blockInfo =
1431*35238bceSAndroid Build Coastguard Worker                 getProgramInterfaceBlockInfo(gl, program.getProgram(), GL_SHADER_STORAGE_BLOCK, blockIndex);
1432*35238bceSAndroid Build Coastguard Worker             const uint32_t valueIndex =
1433*35238bceSAndroid Build Coastguard Worker                 gl.getProgramResourceIndex(program.getProgram(), GL_BUFFER_VARIABLE, "Input.values");
1434*35238bceSAndroid Build Coastguard Worker             const InterfaceVariableInfo valueInfo =
1435*35238bceSAndroid Build Coastguard Worker                 getProgramInterfaceVariableInfo(gl, program.getProgram(), GL_BUFFER_VARIABLE, valueIndex);
1436*35238bceSAndroid Build Coastguard Worker 
1437*35238bceSAndroid Build Coastguard Worker             gl.bindBuffer(GL_SHADER_STORAGE_BUFFER, *inputBuffer);
1438*35238bceSAndroid Build Coastguard Worker             gl.bufferData(GL_SHADER_STORAGE_BUFFER, (glw::GLsizeiptr)blockInfo.dataSize, DE_NULL, GL_STATIC_DRAW);
1439*35238bceSAndroid Build Coastguard Worker 
1440*35238bceSAndroid Build Coastguard Worker             TCU_CHECK(valueInfo.arraySize == (uint32_t)inputValues.size());
1441*35238bceSAndroid Build Coastguard Worker 
1442*35238bceSAndroid Build Coastguard Worker             {
1443*35238bceSAndroid Build Coastguard Worker                 const BufferMemMap bufMap(gl, GL_SHADER_STORAGE_BUFFER, 0, (int)blockInfo.dataSize, GL_MAP_WRITE_BIT);
1444*35238bceSAndroid Build Coastguard Worker 
1445*35238bceSAndroid Build Coastguard Worker                 for (uint32_t ndx = 0; ndx < (uint32_t)inputValues.size(); ndx++)
1446*35238bceSAndroid Build Coastguard Worker                     *(uint32_t *)((uint8_t *)bufMap.getPtr() + valueInfo.offset + ndx * valueInfo.arrayStride) =
1447*35238bceSAndroid Build Coastguard Worker                         inputValues[ndx];
1448*35238bceSAndroid Build Coastguard Worker             }
1449*35238bceSAndroid Build Coastguard Worker 
1450*35238bceSAndroid Build Coastguard Worker             gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, blockInfo.bufferBinding, *inputBuffer);
1451*35238bceSAndroid Build Coastguard Worker             GLU_EXPECT_NO_ERROR(gl.getError(), "Input buffer setup failed");
1452*35238bceSAndroid Build Coastguard Worker         }
1453*35238bceSAndroid Build Coastguard Worker 
1454*35238bceSAndroid Build Coastguard Worker         // Output image setup
1455*35238bceSAndroid Build Coastguard Worker         gl.bindTexture(GL_TEXTURE_2D, *outputTexture);
1456*35238bceSAndroid Build Coastguard Worker         gl.texStorage2D(GL_TEXTURE_2D, 1, GL_R32UI, m_imageSize[0], m_imageSize[1]);
1457*35238bceSAndroid Build Coastguard Worker         gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1458*35238bceSAndroid Build Coastguard Worker         gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1459*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(gl.getError(), "Uploading image data failed");
1460*35238bceSAndroid Build Coastguard Worker 
1461*35238bceSAndroid Build Coastguard Worker         // Bind to unit 1
1462*35238bceSAndroid Build Coastguard Worker         gl.bindImageTexture(1, *outputTexture, 0, GL_FALSE, 0, GL_READ_WRITE, GL_R32UI);
1463*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(gl.getError(), "Image setup failed");
1464*35238bceSAndroid Build Coastguard Worker 
1465*35238bceSAndroid Build Coastguard Worker         // Dispatch compute workload
1466*35238bceSAndroid Build Coastguard Worker         gl.dispatchCompute(m_imageSize[0], m_imageSize[1], 1);
1467*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(gl.getError(), "glDispatchCompute()");
1468*35238bceSAndroid Build Coastguard Worker 
1469*35238bceSAndroid Build Coastguard Worker         // Read back and compare
1470*35238bceSAndroid Build Coastguard Worker         {
1471*35238bceSAndroid Build Coastguard Worker             Framebuffer fbo(m_context.getRenderContext());
1472*35238bceSAndroid Build Coastguard Worker             vector<uint32_t> pixels(m_imageSize[0] * m_imageSize[1] * 4);
1473*35238bceSAndroid Build Coastguard Worker 
1474*35238bceSAndroid Build Coastguard Worker             gl.bindFramebuffer(GL_FRAMEBUFFER, *fbo);
1475*35238bceSAndroid Build Coastguard Worker             gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, *outputTexture, 0);
1476*35238bceSAndroid Build Coastguard Worker             TCU_CHECK(gl.checkFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
1477*35238bceSAndroid Build Coastguard Worker 
1478*35238bceSAndroid Build Coastguard Worker             // \note In ES3 we have to use GL_RGBA_INTEGER
1479*35238bceSAndroid Build Coastguard Worker             gl.readBuffer(GL_COLOR_ATTACHMENT0);
1480*35238bceSAndroid Build Coastguard Worker             gl.readPixels(0, 0, m_imageSize[0], m_imageSize[1], GL_RGBA_INTEGER, GL_UNSIGNED_INT, &pixels[0]);
1481*35238bceSAndroid Build Coastguard Worker             GLU_EXPECT_NO_ERROR(gl.getError(), "Reading pixels failed");
1482*35238bceSAndroid Build Coastguard Worker 
1483*35238bceSAndroid Build Coastguard Worker             for (int pixelNdx = 0; pixelNdx < (int)inputValues.size() / m_localSize; pixelNdx++)
1484*35238bceSAndroid Build Coastguard Worker             {
1485*35238bceSAndroid Build Coastguard Worker                 const uint32_t res = pixels[pixelNdx * 4];
1486*35238bceSAndroid Build Coastguard Worker                 uint32_t ref       = 0;
1487*35238bceSAndroid Build Coastguard Worker 
1488*35238bceSAndroid Build Coastguard Worker                 for (int offs = 0; offs < m_localSize; offs++)
1489*35238bceSAndroid Build Coastguard Worker                     ref += inputValues[pixelNdx * m_localSize + offs];
1490*35238bceSAndroid Build Coastguard Worker 
1491*35238bceSAndroid Build Coastguard Worker                 if (res != ref)
1492*35238bceSAndroid Build Coastguard Worker                     throw tcu::TestError(string("Comparison failed for pixel ") + de::toString(pixelNdx));
1493*35238bceSAndroid Build Coastguard Worker             }
1494*35238bceSAndroid Build Coastguard Worker         }
1495*35238bceSAndroid Build Coastguard Worker 
1496*35238bceSAndroid Build Coastguard Worker         m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1497*35238bceSAndroid Build Coastguard Worker         return STOP;
1498*35238bceSAndroid Build Coastguard Worker     }
1499*35238bceSAndroid Build Coastguard Worker 
1500*35238bceSAndroid Build Coastguard Worker private:
1501*35238bceSAndroid Build Coastguard Worker     const int m_localSize;
1502*35238bceSAndroid Build Coastguard Worker     const tcu::IVec2 m_imageSize;
1503*35238bceSAndroid Build Coastguard Worker };
1504*35238bceSAndroid Build Coastguard Worker 
1505*35238bceSAndroid Build Coastguard Worker class ImageBarrierCase : public TestCase
1506*35238bceSAndroid Build Coastguard Worker {
1507*35238bceSAndroid Build Coastguard Worker public:
ImageBarrierCase(Context & context,const char * name,const char * description,const tcu::IVec2 & workSize)1508*35238bceSAndroid Build Coastguard Worker     ImageBarrierCase(Context &context, const char *name, const char *description, const tcu::IVec2 &workSize)
1509*35238bceSAndroid Build Coastguard Worker         : TestCase(context, name, description)
1510*35238bceSAndroid Build Coastguard Worker         , m_workSize(workSize)
1511*35238bceSAndroid Build Coastguard Worker     {
1512*35238bceSAndroid Build Coastguard Worker     }
1513*35238bceSAndroid Build Coastguard Worker 
iterate(void)1514*35238bceSAndroid Build Coastguard Worker     IterateResult iterate(void)
1515*35238bceSAndroid Build Coastguard Worker     {
1516*35238bceSAndroid Build Coastguard Worker         const GLSLVersion glslVersion = glu::getContextTypeGLSLVersion(m_context.getRenderContext().getType());
1517*35238bceSAndroid Build Coastguard Worker         const char *const glslVersionDeclaration = getGLSLVersionDeclaration(glslVersion);
1518*35238bceSAndroid Build Coastguard Worker 
1519*35238bceSAndroid Build Coastguard Worker         std::ostringstream src0;
1520*35238bceSAndroid Build Coastguard Worker         src0 << glslVersionDeclaration << "\n"
1521*35238bceSAndroid Build Coastguard Worker              << "layout (local_size_x = 1) in;\n"
1522*35238bceSAndroid Build Coastguard Worker                 "uniform uint u_baseVal;\n"
1523*35238bceSAndroid Build Coastguard Worker                 "layout(r32ui, binding = 2) writeonly uniform highp uimage2D u_img;\n"
1524*35238bceSAndroid Build Coastguard Worker                 "void main (void) {\n"
1525*35238bceSAndroid Build Coastguard Worker                 "    uint offset = gl_NumWorkGroups.x*gl_NumWorkGroups.y*gl_WorkGroupID.z + "
1526*35238bceSAndroid Build Coastguard Worker                 "gl_NumWorkGroups.x*gl_WorkGroupID.y + gl_WorkGroupID.x;\n"
1527*35238bceSAndroid Build Coastguard Worker                 "    imageStore(u_img, ivec2(gl_WorkGroupID.xy), uvec4(offset+u_baseVal, 0, 0, 0));\n"
1528*35238bceSAndroid Build Coastguard Worker                 "}\n";
1529*35238bceSAndroid Build Coastguard Worker 
1530*35238bceSAndroid Build Coastguard Worker         std::ostringstream src1;
1531*35238bceSAndroid Build Coastguard Worker         src1 << glslVersionDeclaration << "\n"
1532*35238bceSAndroid Build Coastguard Worker              << "layout (local_size_x = 1) in;\n"
1533*35238bceSAndroid Build Coastguard Worker                 "layout(r32ui, binding = 2) readonly uniform highp uimage2D u_img;\n"
1534*35238bceSAndroid Build Coastguard Worker                 "layout(binding = 0) buffer Output {\n"
1535*35238bceSAndroid Build Coastguard Worker                 "    coherent uint sum;\n"
1536*35238bceSAndroid Build Coastguard Worker                 "};\n"
1537*35238bceSAndroid Build Coastguard Worker                 "void main (void) {\n"
1538*35238bceSAndroid Build Coastguard Worker                 "    uint value = imageLoad(u_img, ivec2(gl_WorkGroupID.xy)).x;\n"
1539*35238bceSAndroid Build Coastguard Worker                 "    atomicAdd(sum, value);\n"
1540*35238bceSAndroid Build Coastguard Worker                 "}\n";
1541*35238bceSAndroid Build Coastguard Worker 
1542*35238bceSAndroid Build Coastguard Worker         const ShaderProgram program0(m_context.getRenderContext(), ProgramSources() << ComputeSource(src0.str()));
1543*35238bceSAndroid Build Coastguard Worker         const ShaderProgram program1(m_context.getRenderContext(), ProgramSources() << ComputeSource(src1.str()));
1544*35238bceSAndroid Build Coastguard Worker 
1545*35238bceSAndroid Build Coastguard Worker         const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1546*35238bceSAndroid Build Coastguard Worker         const Texture tempTexture(m_context.getRenderContext());
1547*35238bceSAndroid Build Coastguard Worker         const Buffer outputBuffer(m_context.getRenderContext());
1548*35238bceSAndroid Build Coastguard Worker         const uint32_t baseValue = 127;
1549*35238bceSAndroid Build Coastguard Worker 
1550*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << program0 << program1;
1551*35238bceSAndroid Build Coastguard Worker         if (!program0.isOk() || !program1.isOk())
1552*35238bceSAndroid Build Coastguard Worker             TCU_FAIL("Compile failed");
1553*35238bceSAndroid Build Coastguard Worker 
1554*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << TestLog::Message << "Work groups: " << m_workSize << TestLog::EndMessage;
1555*35238bceSAndroid Build Coastguard Worker 
1556*35238bceSAndroid Build Coastguard Worker         // Temp texture setup
1557*35238bceSAndroid Build Coastguard Worker         gl.bindTexture(GL_TEXTURE_2D, *tempTexture);
1558*35238bceSAndroid Build Coastguard Worker         gl.texStorage2D(GL_TEXTURE_2D, 1, GL_R32UI, m_workSize[0], m_workSize[1]);
1559*35238bceSAndroid Build Coastguard Worker         gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1560*35238bceSAndroid Build Coastguard Worker         gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1561*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(gl.getError(), "Uploading image data failed");
1562*35238bceSAndroid Build Coastguard Worker 
1563*35238bceSAndroid Build Coastguard Worker         // Bind to unit 2
1564*35238bceSAndroid Build Coastguard Worker         gl.bindImageTexture(2, *tempTexture, 0, GL_FALSE, 0, GL_READ_WRITE, GL_R32UI);
1565*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(gl.getError(), "Image setup failed");
1566*35238bceSAndroid Build Coastguard Worker 
1567*35238bceSAndroid Build Coastguard Worker         // Output buffer setup
1568*35238bceSAndroid Build Coastguard Worker         {
1569*35238bceSAndroid Build Coastguard Worker             const uint32_t blockIndex =
1570*35238bceSAndroid Build Coastguard Worker                 gl.getProgramResourceIndex(program1.getProgram(), GL_SHADER_STORAGE_BLOCK, "Output");
1571*35238bceSAndroid Build Coastguard Worker             const int blockSize = getProgramResourceInt(gl, program1.getProgram(), GL_SHADER_STORAGE_BLOCK, blockIndex,
1572*35238bceSAndroid Build Coastguard Worker                                                         GL_BUFFER_DATA_SIZE);
1573*35238bceSAndroid Build Coastguard Worker 
1574*35238bceSAndroid Build Coastguard Worker             gl.bindBuffer(GL_SHADER_STORAGE_BUFFER, *outputBuffer);
1575*35238bceSAndroid Build Coastguard Worker             gl.bufferData(GL_SHADER_STORAGE_BUFFER, blockSize, DE_NULL, GL_STREAM_READ);
1576*35238bceSAndroid Build Coastguard Worker 
1577*35238bceSAndroid Build Coastguard Worker             {
1578*35238bceSAndroid Build Coastguard Worker                 const BufferMemMap bufMap(gl, GL_SHADER_STORAGE_BUFFER, 0, blockSize, GL_MAP_WRITE_BIT);
1579*35238bceSAndroid Build Coastguard Worker                 deMemset(bufMap.getPtr(), 0, blockSize);
1580*35238bceSAndroid Build Coastguard Worker             }
1581*35238bceSAndroid Build Coastguard Worker 
1582*35238bceSAndroid Build Coastguard Worker             gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, *outputBuffer);
1583*35238bceSAndroid Build Coastguard Worker             GLU_EXPECT_NO_ERROR(gl.getError(), "Output buffer setup failed");
1584*35238bceSAndroid Build Coastguard Worker         }
1585*35238bceSAndroid Build Coastguard Worker 
1586*35238bceSAndroid Build Coastguard Worker         // Dispatch compute workload
1587*35238bceSAndroid Build Coastguard Worker         gl.useProgram(program0.getProgram());
1588*35238bceSAndroid Build Coastguard Worker         gl.uniform1ui(gl.getUniformLocation(program0.getProgram(), "u_baseVal"), baseValue);
1589*35238bceSAndroid Build Coastguard Worker         gl.dispatchCompute(m_workSize[0], m_workSize[1], 1);
1590*35238bceSAndroid Build Coastguard Worker         gl.memoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
1591*35238bceSAndroid Build Coastguard Worker         gl.useProgram(program1.getProgram());
1592*35238bceSAndroid Build Coastguard Worker         gl.dispatchCompute(m_workSize[0], m_workSize[1], 1);
1593*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to dispatch commands");
1594*35238bceSAndroid Build Coastguard Worker 
1595*35238bceSAndroid Build Coastguard Worker         // Read back and compare
1596*35238bceSAndroid Build Coastguard Worker         {
1597*35238bceSAndroid Build Coastguard Worker             const uint32_t blockIndex =
1598*35238bceSAndroid Build Coastguard Worker                 gl.getProgramResourceIndex(program1.getProgram(), GL_SHADER_STORAGE_BLOCK, "Output");
1599*35238bceSAndroid Build Coastguard Worker             const int blockSize = getProgramResourceInt(gl, program1.getProgram(), GL_SHADER_STORAGE_BLOCK, blockIndex,
1600*35238bceSAndroid Build Coastguard Worker                                                         GL_BUFFER_DATA_SIZE);
1601*35238bceSAndroid Build Coastguard Worker             const uint32_t valueIndex = gl.getProgramResourceIndex(program1.getProgram(), GL_BUFFER_VARIABLE, "sum");
1602*35238bceSAndroid Build Coastguard Worker             const InterfaceVariableInfo valueInfo =
1603*35238bceSAndroid Build Coastguard Worker                 getProgramInterfaceVariableInfo(gl, program1.getProgram(), GL_BUFFER_VARIABLE, valueIndex);
1604*35238bceSAndroid Build Coastguard Worker             const BufferMemMap bufMap(gl, GL_SHADER_STORAGE_BUFFER, 0, blockSize, GL_MAP_READ_BIT);
1605*35238bceSAndroid Build Coastguard Worker 
1606*35238bceSAndroid Build Coastguard Worker             const uint32_t res = *((const uint32_t *)((const uint8_t *)bufMap.getPtr() + valueInfo.offset));
1607*35238bceSAndroid Build Coastguard Worker             uint32_t ref       = 0;
1608*35238bceSAndroid Build Coastguard Worker 
1609*35238bceSAndroid Build Coastguard Worker             for (int ndx = 0; ndx < m_workSize[0] * m_workSize[1]; ndx++)
1610*35238bceSAndroid Build Coastguard Worker                 ref += baseValue + (uint32_t)ndx;
1611*35238bceSAndroid Build Coastguard Worker 
1612*35238bceSAndroid Build Coastguard Worker             if (res != ref)
1613*35238bceSAndroid Build Coastguard Worker             {
1614*35238bceSAndroid Build Coastguard Worker                 m_testCtx.getLog() << TestLog::Message << "ERROR: comparison failed, expected " << ref << ", got "
1615*35238bceSAndroid Build Coastguard Worker                                    << res << TestLog::EndMessage;
1616*35238bceSAndroid Build Coastguard Worker                 throw tcu::TestError("Comparison failed");
1617*35238bceSAndroid Build Coastguard Worker             }
1618*35238bceSAndroid Build Coastguard Worker         }
1619*35238bceSAndroid Build Coastguard Worker 
1620*35238bceSAndroid Build Coastguard Worker         m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1621*35238bceSAndroid Build Coastguard Worker         return STOP;
1622*35238bceSAndroid Build Coastguard Worker     }
1623*35238bceSAndroid Build Coastguard Worker 
1624*35238bceSAndroid Build Coastguard Worker private:
1625*35238bceSAndroid Build Coastguard Worker     const tcu::IVec2 m_workSize;
1626*35238bceSAndroid Build Coastguard Worker };
1627*35238bceSAndroid Build Coastguard Worker 
1628*35238bceSAndroid Build Coastguard Worker class AtomicCounterCase : public TestCase
1629*35238bceSAndroid Build Coastguard Worker {
1630*35238bceSAndroid Build Coastguard Worker public:
AtomicCounterCase(Context & context,const char * name,const char * description,const tcu::IVec3 & localSize,const tcu::IVec3 & workSize)1631*35238bceSAndroid Build Coastguard Worker     AtomicCounterCase(Context &context, const char *name, const char *description, const tcu::IVec3 &localSize,
1632*35238bceSAndroid Build Coastguard Worker                       const tcu::IVec3 &workSize)
1633*35238bceSAndroid Build Coastguard Worker         : TestCase(context, name, description)
1634*35238bceSAndroid Build Coastguard Worker         , m_localSize(localSize)
1635*35238bceSAndroid Build Coastguard Worker         , m_workSize(workSize)
1636*35238bceSAndroid Build Coastguard Worker     {
1637*35238bceSAndroid Build Coastguard Worker     }
1638*35238bceSAndroid Build Coastguard Worker 
iterate(void)1639*35238bceSAndroid Build Coastguard Worker     IterateResult iterate(void)
1640*35238bceSAndroid Build Coastguard Worker     {
1641*35238bceSAndroid Build Coastguard Worker         const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1642*35238bceSAndroid Build Coastguard Worker         const Buffer outputBuffer(m_context.getRenderContext());
1643*35238bceSAndroid Build Coastguard Worker         const Buffer counterBuffer(m_context.getRenderContext());
1644*35238bceSAndroid Build Coastguard Worker         const int workGroupSize  = m_localSize[0] * m_localSize[1] * m_localSize[2];
1645*35238bceSAndroid Build Coastguard Worker         const int workGroupCount = m_workSize[0] * m_workSize[1] * m_workSize[2];
1646*35238bceSAndroid Build Coastguard Worker         const int numValues      = workGroupSize * workGroupCount;
1647*35238bceSAndroid Build Coastguard Worker 
1648*35238bceSAndroid Build Coastguard Worker         const GLSLVersion glslVersion = glu::getContextTypeGLSLVersion(m_context.getRenderContext().getType());
1649*35238bceSAndroid Build Coastguard Worker         std::ostringstream src;
1650*35238bceSAndroid Build Coastguard Worker 
1651*35238bceSAndroid Build Coastguard Worker         src << getGLSLVersionDeclaration(glslVersion) << "\n"
1652*35238bceSAndroid Build Coastguard Worker             << "layout (local_size_x = " << m_localSize[0] << ", local_size_y = " << m_localSize[1]
1653*35238bceSAndroid Build Coastguard Worker             << ", local_size_z = " << m_localSize[2] << ") in;\n"
1654*35238bceSAndroid Build Coastguard Worker             << "layout(binding = 0) buffer Output {\n"
1655*35238bceSAndroid Build Coastguard Worker             << "    uint values[" << numValues << "];\n"
1656*35238bceSAndroid Build Coastguard Worker             << "} sb_out;\n\n"
1657*35238bceSAndroid Build Coastguard Worker             << "layout(binding = 0, offset = 0) uniform atomic_uint u_count;\n\n"
1658*35238bceSAndroid Build Coastguard Worker             << "void main (void) {\n"
1659*35238bceSAndroid Build Coastguard Worker             << "    uint localSize  = gl_WorkGroupSize.x*gl_WorkGroupSize.y*gl_WorkGroupSize.z;\n"
1660*35238bceSAndroid Build Coastguard Worker             << "    uint globalNdx  = gl_NumWorkGroups.x*gl_NumWorkGroups.y*gl_WorkGroupID.z + "
1661*35238bceSAndroid Build Coastguard Worker                "gl_NumWorkGroups.x*gl_WorkGroupID.y + gl_WorkGroupID.x;\n"
1662*35238bceSAndroid Build Coastguard Worker             << "    uint globalOffs = localSize*globalNdx;\n"
1663*35238bceSAndroid Build Coastguard Worker             << "    uint localOffs  = gl_WorkGroupSize.x*gl_WorkGroupSize.y*gl_LocalInvocationID.z + "
1664*35238bceSAndroid Build Coastguard Worker                "gl_WorkGroupSize.x*gl_LocalInvocationID.y + gl_LocalInvocationID.x;\n"
1665*35238bceSAndroid Build Coastguard Worker             << "\n"
1666*35238bceSAndroid Build Coastguard Worker             << "    uint oldVal = atomicCounterIncrement(u_count);\n"
1667*35238bceSAndroid Build Coastguard Worker             << "    sb_out.values[globalOffs+localOffs] = oldVal;\n"
1668*35238bceSAndroid Build Coastguard Worker             << "}\n";
1669*35238bceSAndroid Build Coastguard Worker 
1670*35238bceSAndroid Build Coastguard Worker         const ShaderProgram program(m_context.getRenderContext(), ProgramSources() << ComputeSource(src.str()));
1671*35238bceSAndroid Build Coastguard Worker 
1672*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << program;
1673*35238bceSAndroid Build Coastguard Worker         if (!program.isOk())
1674*35238bceSAndroid Build Coastguard Worker             TCU_FAIL("Compile failed");
1675*35238bceSAndroid Build Coastguard Worker 
1676*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << TestLog::Message << "Work groups: " << m_workSize << TestLog::EndMessage;
1677*35238bceSAndroid Build Coastguard Worker 
1678*35238bceSAndroid Build Coastguard Worker         gl.useProgram(program.getProgram());
1679*35238bceSAndroid Build Coastguard Worker 
1680*35238bceSAndroid Build Coastguard Worker         // Atomic counter buffer setup
1681*35238bceSAndroid Build Coastguard Worker         {
1682*35238bceSAndroid Build Coastguard Worker             const uint32_t uniformIndex = gl.getProgramResourceIndex(program.getProgram(), GL_UNIFORM, "u_count");
1683*35238bceSAndroid Build Coastguard Worker             const uint32_t bufferIndex  = getProgramResourceUint(gl, program.getProgram(), GL_UNIFORM, uniformIndex,
1684*35238bceSAndroid Build Coastguard Worker                                                                  GL_ATOMIC_COUNTER_BUFFER_INDEX);
1685*35238bceSAndroid Build Coastguard Worker             const uint32_t bufferSize   = getProgramResourceUint(gl, program.getProgram(), GL_ATOMIC_COUNTER_BUFFER,
1686*35238bceSAndroid Build Coastguard Worker                                                                  bufferIndex, GL_BUFFER_DATA_SIZE);
1687*35238bceSAndroid Build Coastguard Worker 
1688*35238bceSAndroid Build Coastguard Worker             gl.bindBuffer(GL_ATOMIC_COUNTER_BUFFER, *counterBuffer);
1689*35238bceSAndroid Build Coastguard Worker             gl.bufferData(GL_ATOMIC_COUNTER_BUFFER, bufferSize, DE_NULL, GL_STREAM_READ);
1690*35238bceSAndroid Build Coastguard Worker 
1691*35238bceSAndroid Build Coastguard Worker             {
1692*35238bceSAndroid Build Coastguard Worker                 const BufferMemMap memMap(gl, GL_ATOMIC_COUNTER_BUFFER, 0, bufferSize, GL_MAP_WRITE_BIT);
1693*35238bceSAndroid Build Coastguard Worker                 deMemset(memMap.getPtr(), 0, (int)bufferSize);
1694*35238bceSAndroid Build Coastguard Worker             }
1695*35238bceSAndroid Build Coastguard Worker 
1696*35238bceSAndroid Build Coastguard Worker             gl.bindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0, *counterBuffer);
1697*35238bceSAndroid Build Coastguard Worker             GLU_EXPECT_NO_ERROR(gl.getError(), "Atomic counter buffer setup failed");
1698*35238bceSAndroid Build Coastguard Worker         }
1699*35238bceSAndroid Build Coastguard Worker 
1700*35238bceSAndroid Build Coastguard Worker         // Output buffer setup
1701*35238bceSAndroid Build Coastguard Worker         {
1702*35238bceSAndroid Build Coastguard Worker             const uint32_t blockIndex =
1703*35238bceSAndroid Build Coastguard Worker                 gl.getProgramResourceIndex(program.getProgram(), GL_SHADER_STORAGE_BLOCK, "Output");
1704*35238bceSAndroid Build Coastguard Worker             const int blockSize = getProgramResourceInt(gl, program.getProgram(), GL_SHADER_STORAGE_BLOCK, blockIndex,
1705*35238bceSAndroid Build Coastguard Worker                                                         GL_BUFFER_DATA_SIZE);
1706*35238bceSAndroid Build Coastguard Worker 
1707*35238bceSAndroid Build Coastguard Worker             gl.bindBuffer(GL_SHADER_STORAGE_BUFFER, *outputBuffer);
1708*35238bceSAndroid Build Coastguard Worker             gl.bufferData(GL_SHADER_STORAGE_BUFFER, blockSize, DE_NULL, GL_STREAM_READ);
1709*35238bceSAndroid Build Coastguard Worker             gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, *outputBuffer);
1710*35238bceSAndroid Build Coastguard Worker             GLU_EXPECT_NO_ERROR(gl.getError(), "Output buffer setup failed");
1711*35238bceSAndroid Build Coastguard Worker         }
1712*35238bceSAndroid Build Coastguard Worker 
1713*35238bceSAndroid Build Coastguard Worker         // Dispatch compute workload
1714*35238bceSAndroid Build Coastguard Worker         gl.dispatchCompute(m_workSize[0], m_workSize[1], m_workSize[2]);
1715*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(gl.getError(), "glDispatchCompute()");
1716*35238bceSAndroid Build Coastguard Worker 
1717*35238bceSAndroid Build Coastguard Worker         // Read back and compare atomic counter
1718*35238bceSAndroid Build Coastguard Worker         {
1719*35238bceSAndroid Build Coastguard Worker             const uint32_t uniformIndex = gl.getProgramResourceIndex(program.getProgram(), GL_UNIFORM, "u_count");
1720*35238bceSAndroid Build Coastguard Worker             const uint32_t uniformOffset =
1721*35238bceSAndroid Build Coastguard Worker                 getProgramResourceUint(gl, program.getProgram(), GL_UNIFORM, uniformIndex, GL_OFFSET);
1722*35238bceSAndroid Build Coastguard Worker             const uint32_t bufferIndex = getProgramResourceUint(gl, program.getProgram(), GL_UNIFORM, uniformIndex,
1723*35238bceSAndroid Build Coastguard Worker                                                                 GL_ATOMIC_COUNTER_BUFFER_INDEX);
1724*35238bceSAndroid Build Coastguard Worker             const uint32_t bufferSize  = getProgramResourceUint(gl, program.getProgram(), GL_ATOMIC_COUNTER_BUFFER,
1725*35238bceSAndroid Build Coastguard Worker                                                                 bufferIndex, GL_BUFFER_DATA_SIZE);
1726*35238bceSAndroid Build Coastguard Worker             const BufferMemMap bufMap(gl, GL_ATOMIC_COUNTER_BUFFER, 0, bufferSize, GL_MAP_READ_BIT);
1727*35238bceSAndroid Build Coastguard Worker 
1728*35238bceSAndroid Build Coastguard Worker             const uint32_t resVal = *((const uint32_t *)((const uint8_t *)bufMap.getPtr() + uniformOffset));
1729*35238bceSAndroid Build Coastguard Worker 
1730*35238bceSAndroid Build Coastguard Worker             if (resVal != (uint32_t)numValues)
1731*35238bceSAndroid Build Coastguard Worker                 throw tcu::TestError("Invalid atomic counter value");
1732*35238bceSAndroid Build Coastguard Worker         }
1733*35238bceSAndroid Build Coastguard Worker 
1734*35238bceSAndroid Build Coastguard Worker         // Read back and compare SSBO
1735*35238bceSAndroid Build Coastguard Worker         {
1736*35238bceSAndroid Build Coastguard Worker             const uint32_t blockIndex =
1737*35238bceSAndroid Build Coastguard Worker                 gl.getProgramResourceIndex(program.getProgram(), GL_SHADER_STORAGE_BLOCK, "Output");
1738*35238bceSAndroid Build Coastguard Worker             const int blockSize = getProgramResourceInt(gl, program.getProgram(), GL_SHADER_STORAGE_BLOCK, blockIndex,
1739*35238bceSAndroid Build Coastguard Worker                                                         GL_BUFFER_DATA_SIZE);
1740*35238bceSAndroid Build Coastguard Worker             const uint32_t valueIndex =
1741*35238bceSAndroid Build Coastguard Worker                 gl.getProgramResourceIndex(program.getProgram(), GL_BUFFER_VARIABLE, "Output.values");
1742*35238bceSAndroid Build Coastguard Worker             const InterfaceVariableInfo valueInfo =
1743*35238bceSAndroid Build Coastguard Worker                 getProgramInterfaceVariableInfo(gl, program.getProgram(), GL_BUFFER_VARIABLE, valueIndex);
1744*35238bceSAndroid Build Coastguard Worker             const BufferMemMap bufMap(gl, GL_SHADER_STORAGE_BUFFER, 0, blockSize, GL_MAP_READ_BIT);
1745*35238bceSAndroid Build Coastguard Worker             uint32_t valSum = 0;
1746*35238bceSAndroid Build Coastguard Worker             uint32_t refSum = 0;
1747*35238bceSAndroid Build Coastguard Worker 
1748*35238bceSAndroid Build Coastguard Worker             for (int valNdx = 0; valNdx < numValues; valNdx++)
1749*35238bceSAndroid Build Coastguard Worker             {
1750*35238bceSAndroid Build Coastguard Worker                 const uint32_t res = *((const uint32_t *)((const uint8_t *)bufMap.getPtr() + valueInfo.offset +
1751*35238bceSAndroid Build Coastguard Worker                                                           valueInfo.arrayStride * valNdx));
1752*35238bceSAndroid Build Coastguard Worker 
1753*35238bceSAndroid Build Coastguard Worker                 valSum += res;
1754*35238bceSAndroid Build Coastguard Worker                 refSum += (uint32_t)valNdx;
1755*35238bceSAndroid Build Coastguard Worker 
1756*35238bceSAndroid Build Coastguard Worker                 if (!de::inBounds<uint32_t>(res, 0, (uint32_t)numValues))
1757*35238bceSAndroid Build Coastguard Worker                     throw tcu::TestError(string("Comparison failed for Output.values[") + de::toString(valNdx) + "]");
1758*35238bceSAndroid Build Coastguard Worker             }
1759*35238bceSAndroid Build Coastguard Worker 
1760*35238bceSAndroid Build Coastguard Worker             if (valSum != refSum)
1761*35238bceSAndroid Build Coastguard Worker                 throw tcu::TestError("Total sum of values in Output.values doesn't match");
1762*35238bceSAndroid Build Coastguard Worker         }
1763*35238bceSAndroid Build Coastguard Worker 
1764*35238bceSAndroid Build Coastguard Worker         m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1765*35238bceSAndroid Build Coastguard Worker         return STOP;
1766*35238bceSAndroid Build Coastguard Worker     }
1767*35238bceSAndroid Build Coastguard Worker 
1768*35238bceSAndroid Build Coastguard Worker private:
1769*35238bceSAndroid Build Coastguard Worker     const tcu::IVec3 m_localSize;
1770*35238bceSAndroid Build Coastguard Worker     const tcu::IVec3 m_workSize;
1771*35238bceSAndroid Build Coastguard Worker };
1772*35238bceSAndroid Build Coastguard Worker 
1773*35238bceSAndroid Build Coastguard Worker } // namespace
1774*35238bceSAndroid Build Coastguard Worker 
BasicComputeShaderTests(Context & context)1775*35238bceSAndroid Build Coastguard Worker BasicComputeShaderTests::BasicComputeShaderTests(Context &context)
1776*35238bceSAndroid Build Coastguard Worker     : TestCaseGroup(context, "basic", "Basic Compute Shader Tests")
1777*35238bceSAndroid Build Coastguard Worker {
1778*35238bceSAndroid Build Coastguard Worker }
1779*35238bceSAndroid Build Coastguard Worker 
~BasicComputeShaderTests(void)1780*35238bceSAndroid Build Coastguard Worker BasicComputeShaderTests::~BasicComputeShaderTests(void)
1781*35238bceSAndroid Build Coastguard Worker {
1782*35238bceSAndroid Build Coastguard Worker }
1783*35238bceSAndroid Build Coastguard Worker 
init(void)1784*35238bceSAndroid Build Coastguard Worker void BasicComputeShaderTests::init(void)
1785*35238bceSAndroid Build Coastguard Worker {
1786*35238bceSAndroid Build Coastguard Worker     addChild(new EmptyComputeShaderCase(m_context));
1787*35238bceSAndroid Build Coastguard Worker 
1788*35238bceSAndroid Build Coastguard Worker     addChild(new UBOToSSBOInvertCase(m_context, "ubo_to_ssbo_single_invocation",
1789*35238bceSAndroid Build Coastguard Worker                                      "Copy from UBO to SSBO, inverting bits", 256, tcu::IVec3(1, 1, 1),
1790*35238bceSAndroid Build Coastguard Worker                                      tcu::IVec3(1, 1, 1)));
1791*35238bceSAndroid Build Coastguard Worker     addChild(new UBOToSSBOInvertCase(m_context, "ubo_to_ssbo_single_group", "Copy from UBO to SSBO, inverting bits",
1792*35238bceSAndroid Build Coastguard Worker                                      1024, tcu::IVec3(2, 1, 4), tcu::IVec3(1, 1, 1)));
1793*35238bceSAndroid Build Coastguard Worker     addChild(new UBOToSSBOInvertCase(m_context, "ubo_to_ssbo_multiple_invocations",
1794*35238bceSAndroid Build Coastguard Worker                                      "Copy from UBO to SSBO, inverting bits", 1024, tcu::IVec3(1, 1, 1),
1795*35238bceSAndroid Build Coastguard Worker                                      tcu::IVec3(2, 4, 1)));
1796*35238bceSAndroid Build Coastguard Worker     addChild(new UBOToSSBOInvertCase(m_context, "ubo_to_ssbo_multiple_groups", "Copy from UBO to SSBO, inverting bits",
1797*35238bceSAndroid Build Coastguard Worker                                      1024, tcu::IVec3(1, 4, 2), tcu::IVec3(2, 2, 4)));
1798*35238bceSAndroid Build Coastguard Worker 
1799*35238bceSAndroid Build Coastguard Worker     addChild(new CopyInvertSSBOCase(m_context, "copy_ssbo_single_invocation", "Copy between SSBOs, inverting bits", 256,
1800*35238bceSAndroid Build Coastguard Worker                                     tcu::IVec3(1, 1, 1), tcu::IVec3(1, 1, 1)));
1801*35238bceSAndroid Build Coastguard Worker     addChild(new CopyInvertSSBOCase(m_context, "copy_ssbo_multiple_invocations", "Copy between SSBOs, inverting bits",
1802*35238bceSAndroid Build Coastguard Worker                                     1024, tcu::IVec3(1, 1, 1), tcu::IVec3(2, 4, 1)));
1803*35238bceSAndroid Build Coastguard Worker     addChild(new CopyInvertSSBOCase(m_context, "copy_ssbo_multiple_groups", "Copy between SSBOs, inverting bits", 1024,
1804*35238bceSAndroid Build Coastguard Worker                                     tcu::IVec3(1, 4, 2), tcu::IVec3(2, 2, 4)));
1805*35238bceSAndroid Build Coastguard Worker 
1806*35238bceSAndroid Build Coastguard Worker     addChild(new InvertSSBOInPlaceCase(m_context, "ssbo_rw_single_invocation", "Read and write same SSBO", 256, true,
1807*35238bceSAndroid Build Coastguard Worker                                        tcu::IVec3(1, 1, 1), tcu::IVec3(1, 1, 1)));
1808*35238bceSAndroid Build Coastguard Worker     addChild(new InvertSSBOInPlaceCase(m_context, "ssbo_rw_multiple_groups", "Read and write same SSBO", 1024, true,
1809*35238bceSAndroid Build Coastguard Worker                                        tcu::IVec3(1, 4, 2), tcu::IVec3(2, 2, 4)));
1810*35238bceSAndroid Build Coastguard Worker 
1811*35238bceSAndroid Build Coastguard Worker     addChild(new InvertSSBOInPlaceCase(m_context, "ssbo_unsized_arr_single_invocation", "Read and write same SSBO", 256,
1812*35238bceSAndroid Build Coastguard Worker                                        false, tcu::IVec3(1, 1, 1), tcu::IVec3(1, 1, 1)));
1813*35238bceSAndroid Build Coastguard Worker     addChild(new InvertSSBOInPlaceCase(m_context, "ssbo_unsized_arr_multiple_groups", "Read and write same SSBO", 1024,
1814*35238bceSAndroid Build Coastguard Worker                                        false, tcu::IVec3(1, 4, 2), tcu::IVec3(2, 2, 4)));
1815*35238bceSAndroid Build Coastguard Worker 
1816*35238bceSAndroid Build Coastguard Worker     addChild(new WriteToMultipleSSBOCase(m_context, "write_multiple_arr_single_invocation", "Write to multiple SSBOs",
1817*35238bceSAndroid Build Coastguard Worker                                          256, true, tcu::IVec3(1, 1, 1), tcu::IVec3(1, 1, 1)));
1818*35238bceSAndroid Build Coastguard Worker     addChild(new WriteToMultipleSSBOCase(m_context, "write_multiple_arr_multiple_groups", "Write to multiple SSBOs",
1819*35238bceSAndroid Build Coastguard Worker                                          1024, true, tcu::IVec3(1, 4, 2), tcu::IVec3(2, 2, 4)));
1820*35238bceSAndroid Build Coastguard Worker 
1821*35238bceSAndroid Build Coastguard Worker     addChild(new WriteToMultipleSSBOCase(m_context, "write_multiple_unsized_arr_single_invocation",
1822*35238bceSAndroid Build Coastguard Worker                                          "Write to multiple SSBOs", 256, false, tcu::IVec3(1, 1, 1),
1823*35238bceSAndroid Build Coastguard Worker                                          tcu::IVec3(1, 1, 1)));
1824*35238bceSAndroid Build Coastguard Worker     addChild(new WriteToMultipleSSBOCase(m_context, "write_multiple_unsized_arr_multiple_groups",
1825*35238bceSAndroid Build Coastguard Worker                                          "Write to multiple SSBOs", 1024, false, tcu::IVec3(1, 4, 2),
1826*35238bceSAndroid Build Coastguard Worker                                          tcu::IVec3(2, 2, 4)));
1827*35238bceSAndroid Build Coastguard Worker 
1828*35238bceSAndroid Build Coastguard Worker     addChild(new SSBOLocalBarrierCase(m_context, "ssbo_local_barrier_single_invocation", "SSBO local barrier usage",
1829*35238bceSAndroid Build Coastguard Worker                                       tcu::IVec3(1, 1, 1), tcu::IVec3(1, 1, 1)));
1830*35238bceSAndroid Build Coastguard Worker     addChild(new SSBOLocalBarrierCase(m_context, "ssbo_local_barrier_single_group", "SSBO local barrier usage",
1831*35238bceSAndroid Build Coastguard Worker                                       tcu::IVec3(3, 2, 5), tcu::IVec3(1, 1, 1)));
1832*35238bceSAndroid Build Coastguard Worker     addChild(new SSBOLocalBarrierCase(m_context, "ssbo_local_barrier_multiple_groups", "SSBO local barrier usage",
1833*35238bceSAndroid Build Coastguard Worker                                       tcu::IVec3(3, 4, 1), tcu::IVec3(2, 7, 3)));
1834*35238bceSAndroid Build Coastguard Worker 
1835*35238bceSAndroid Build Coastguard Worker     addChild(
1836*35238bceSAndroid Build Coastguard Worker         new SSBOBarrierCase(m_context, "ssbo_cmd_barrier_single", "SSBO memory barrier usage", tcu::IVec3(1, 1, 1)));
1837*35238bceSAndroid Build Coastguard Worker     addChild(
1838*35238bceSAndroid Build Coastguard Worker         new SSBOBarrierCase(m_context, "ssbo_cmd_barrier_multiple", "SSBO memory barrier usage", tcu::IVec3(11, 5, 7)));
1839*35238bceSAndroid Build Coastguard Worker 
1840*35238bceSAndroid Build Coastguard Worker     addChild(new BasicSharedVarCase(m_context, "shared_var_single_invocation", "Basic shared variable usage",
1841*35238bceSAndroid Build Coastguard Worker                                     tcu::IVec3(1, 1, 1), tcu::IVec3(1, 1, 1)));
1842*35238bceSAndroid Build Coastguard Worker     addChild(new BasicSharedVarCase(m_context, "shared_var_single_group", "Basic shared variable usage",
1843*35238bceSAndroid Build Coastguard Worker                                     tcu::IVec3(3, 2, 5), tcu::IVec3(1, 1, 1)));
1844*35238bceSAndroid Build Coastguard Worker     addChild(new BasicSharedVarCase(m_context, "shared_var_multiple_invocations", "Basic shared variable usage",
1845*35238bceSAndroid Build Coastguard Worker                                     tcu::IVec3(1, 1, 1), tcu::IVec3(2, 5, 4)));
1846*35238bceSAndroid Build Coastguard Worker     addChild(new BasicSharedVarCase(m_context, "shared_var_multiple_groups", "Basic shared variable usage",
1847*35238bceSAndroid Build Coastguard Worker                                     tcu::IVec3(3, 4, 1), tcu::IVec3(2, 7, 3)));
1848*35238bceSAndroid Build Coastguard Worker 
1849*35238bceSAndroid Build Coastguard Worker     addChild(new SharedVarAtomicOpCase(m_context, "shared_atomic_op_single_invocation",
1850*35238bceSAndroid Build Coastguard Worker                                        "Atomic operation with shared var", tcu::IVec3(1, 1, 1), tcu::IVec3(1, 1, 1)));
1851*35238bceSAndroid Build Coastguard Worker     addChild(new SharedVarAtomicOpCase(m_context, "shared_atomic_op_single_group", "Atomic operation with shared var",
1852*35238bceSAndroid Build Coastguard Worker                                        tcu::IVec3(3, 2, 5), tcu::IVec3(1, 1, 1)));
1853*35238bceSAndroid Build Coastguard Worker     addChild(new SharedVarAtomicOpCase(m_context, "shared_atomic_op_multiple_invocations",
1854*35238bceSAndroid Build Coastguard Worker                                        "Atomic operation with shared var", tcu::IVec3(1, 1, 1), tcu::IVec3(2, 5, 4)));
1855*35238bceSAndroid Build Coastguard Worker     addChild(new SharedVarAtomicOpCase(m_context, "shared_atomic_op_multiple_groups",
1856*35238bceSAndroid Build Coastguard Worker                                        "Atomic operation with shared var", tcu::IVec3(3, 4, 1), tcu::IVec3(2, 7, 3)));
1857*35238bceSAndroid Build Coastguard Worker 
1858*35238bceSAndroid Build Coastguard Worker     addChild(new CopyImageToSSBOCase(m_context, "copy_image_to_ssbo_small", "Image to SSBO copy", tcu::IVec2(1, 1),
1859*35238bceSAndroid Build Coastguard Worker                                      tcu::IVec2(64, 64)));
1860*35238bceSAndroid Build Coastguard Worker     addChild(new CopyImageToSSBOCase(m_context, "copy_image_to_ssbo_large", "Image to SSBO copy", tcu::IVec2(2, 4),
1861*35238bceSAndroid Build Coastguard Worker                                      tcu::IVec2(512, 512)));
1862*35238bceSAndroid Build Coastguard Worker 
1863*35238bceSAndroid Build Coastguard Worker     addChild(new CopySSBOToImageCase(m_context, "copy_ssbo_to_image_small", "SSBO to image copy", tcu::IVec2(1, 1),
1864*35238bceSAndroid Build Coastguard Worker                                      tcu::IVec2(64, 64)));
1865*35238bceSAndroid Build Coastguard Worker     addChild(new CopySSBOToImageCase(m_context, "copy_ssbo_to_image_large", "SSBO to image copy", tcu::IVec2(2, 4),
1866*35238bceSAndroid Build Coastguard Worker                                      tcu::IVec2(512, 512)));
1867*35238bceSAndroid Build Coastguard Worker 
1868*35238bceSAndroid Build Coastguard Worker     addChild(new ImageAtomicOpCase(m_context, "image_atomic_op_local_size_1", "Atomic operation with image", 1,
1869*35238bceSAndroid Build Coastguard Worker                                    tcu::IVec2(64, 64)));
1870*35238bceSAndroid Build Coastguard Worker     addChild(new ImageAtomicOpCase(m_context, "image_atomic_op_local_size_8", "Atomic operation with image", 8,
1871*35238bceSAndroid Build Coastguard Worker                                    tcu::IVec2(64, 64)));
1872*35238bceSAndroid Build Coastguard Worker 
1873*35238bceSAndroid Build Coastguard Worker     addChild(new ImageBarrierCase(m_context, "image_barrier_single", "Image barrier", tcu::IVec2(1, 1)));
1874*35238bceSAndroid Build Coastguard Worker     addChild(new ImageBarrierCase(m_context, "image_barrier_multiple", "Image barrier", tcu::IVec2(64, 64)));
1875*35238bceSAndroid Build Coastguard Worker 
1876*35238bceSAndroid Build Coastguard Worker     addChild(new AtomicCounterCase(m_context, "atomic_counter_single_invocation", "Basic atomic counter test",
1877*35238bceSAndroid Build Coastguard Worker                                    tcu::IVec3(1, 1, 1), tcu::IVec3(1, 1, 1)));
1878*35238bceSAndroid Build Coastguard Worker     addChild(new AtomicCounterCase(m_context, "atomic_counter_single_group", "Basic atomic counter test",
1879*35238bceSAndroid Build Coastguard Worker                                    tcu::IVec3(3, 2, 5), tcu::IVec3(1, 1, 1)));
1880*35238bceSAndroid Build Coastguard Worker     addChild(new AtomicCounterCase(m_context, "atomic_counter_multiple_invocations", "Basic atomic counter test",
1881*35238bceSAndroid Build Coastguard Worker                                    tcu::IVec3(1, 1, 1), tcu::IVec3(2, 5, 4)));
1882*35238bceSAndroid Build Coastguard Worker     addChild(new AtomicCounterCase(m_context, "atomic_counter_multiple_groups", "Basic atomic counter test",
1883*35238bceSAndroid Build Coastguard Worker                                    tcu::IVec3(3, 4, 1), tcu::IVec3(2, 7, 3)));
1884*35238bceSAndroid Build Coastguard Worker }
1885*35238bceSAndroid Build Coastguard Worker 
1886*35238bceSAndroid Build Coastguard Worker } // namespace Functional
1887*35238bceSAndroid Build Coastguard Worker } // namespace gles31
1888*35238bceSAndroid Build Coastguard Worker } // namespace deqp
1889