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 Synchronization Tests
22*35238bceSAndroid Build Coastguard Worker *//*--------------------------------------------------------------------*/
23*35238bceSAndroid Build Coastguard Worker
24*35238bceSAndroid Build Coastguard Worker #include "es31fSynchronizationTests.hpp"
25*35238bceSAndroid Build Coastguard Worker #include "tcuTestLog.hpp"
26*35238bceSAndroid Build Coastguard Worker #include "tcuStringTemplate.hpp"
27*35238bceSAndroid Build Coastguard Worker #include "tcuSurface.hpp"
28*35238bceSAndroid Build Coastguard Worker #include "tcuRenderTarget.hpp"
29*35238bceSAndroid Build Coastguard Worker #include "gluRenderContext.hpp"
30*35238bceSAndroid Build Coastguard Worker #include "gluShaderProgram.hpp"
31*35238bceSAndroid Build Coastguard Worker #include "gluObjectWrapper.hpp"
32*35238bceSAndroid Build Coastguard Worker #include "gluPixelTransfer.hpp"
33*35238bceSAndroid Build Coastguard Worker #include "gluContextInfo.hpp"
34*35238bceSAndroid Build Coastguard Worker #include "glwFunctions.hpp"
35*35238bceSAndroid Build Coastguard Worker #include "glwEnums.hpp"
36*35238bceSAndroid Build Coastguard Worker #include "deStringUtil.hpp"
37*35238bceSAndroid Build Coastguard Worker #include "deSharedPtr.hpp"
38*35238bceSAndroid Build Coastguard Worker #include "deMemory.h"
39*35238bceSAndroid Build Coastguard Worker #include "deRandom.hpp"
40*35238bceSAndroid Build Coastguard Worker
41*35238bceSAndroid Build Coastguard Worker #include <map>
42*35238bceSAndroid Build Coastguard Worker
43*35238bceSAndroid Build Coastguard Worker namespace deqp
44*35238bceSAndroid Build Coastguard Worker {
45*35238bceSAndroid Build Coastguard Worker namespace gles31
46*35238bceSAndroid Build Coastguard Worker {
47*35238bceSAndroid Build Coastguard Worker namespace Functional
48*35238bceSAndroid Build Coastguard Worker {
49*35238bceSAndroid Build Coastguard Worker namespace
50*35238bceSAndroid Build Coastguard Worker {
51*35238bceSAndroid Build Coastguard Worker
checkSupport(Context & ctx)52*35238bceSAndroid Build Coastguard Worker static bool checkSupport(Context &ctx)
53*35238bceSAndroid Build Coastguard Worker {
54*35238bceSAndroid Build Coastguard Worker auto ctxType = ctx.getRenderContext().getType();
55*35238bceSAndroid Build Coastguard Worker return contextSupports(ctxType, glu::ApiType::es(3, 2)) || contextSupports(ctxType, glu::ApiType::core(4, 5)) ||
56*35238bceSAndroid Build Coastguard Worker ctx.getContextInfo().isExtensionSupported("GL_OES_shader_image_atomic");
57*35238bceSAndroid Build Coastguard Worker }
58*35238bceSAndroid Build Coastguard Worker
validateSortedAtomicRampAdditionValueChain(const std::vector<uint32_t> & valueChain,uint32_t sumValue,int & invalidOperationNdx,uint32_t & errorDelta,uint32_t & errorExpected)59*35238bceSAndroid Build Coastguard Worker static bool validateSortedAtomicRampAdditionValueChain(const std::vector<uint32_t> &valueChain, uint32_t sumValue,
60*35238bceSAndroid Build Coastguard Worker int &invalidOperationNdx, uint32_t &errorDelta,
61*35238bceSAndroid Build Coastguard Worker uint32_t &errorExpected)
62*35238bceSAndroid Build Coastguard Worker {
63*35238bceSAndroid Build Coastguard Worker std::vector<uint32_t> chainDelta(valueChain.size());
64*35238bceSAndroid Build Coastguard Worker
65*35238bceSAndroid Build Coastguard Worker for (int callNdx = 0; callNdx < (int)valueChain.size(); ++callNdx)
66*35238bceSAndroid Build Coastguard Worker chainDelta[callNdx] =
67*35238bceSAndroid Build Coastguard Worker ((callNdx + 1 == (int)valueChain.size()) ? (sumValue) : (valueChain[callNdx + 1])) - valueChain[callNdx];
68*35238bceSAndroid Build Coastguard Worker
69*35238bceSAndroid Build Coastguard Worker // chainDelta contains now the actual additions applied to the value
70*35238bceSAndroid Build Coastguard Worker // check there exists an addition ramp form 1 to ...
71*35238bceSAndroid Build Coastguard Worker std::sort(chainDelta.begin(), chainDelta.end());
72*35238bceSAndroid Build Coastguard Worker
73*35238bceSAndroid Build Coastguard Worker for (int callNdx = 0; callNdx < (int)valueChain.size(); ++callNdx)
74*35238bceSAndroid Build Coastguard Worker {
75*35238bceSAndroid Build Coastguard Worker if ((int)chainDelta[callNdx] != callNdx + 1)
76*35238bceSAndroid Build Coastguard Worker {
77*35238bceSAndroid Build Coastguard Worker invalidOperationNdx = callNdx;
78*35238bceSAndroid Build Coastguard Worker errorDelta = chainDelta[callNdx];
79*35238bceSAndroid Build Coastguard Worker errorExpected = callNdx + 1;
80*35238bceSAndroid Build Coastguard Worker
81*35238bceSAndroid Build Coastguard Worker return false;
82*35238bceSAndroid Build Coastguard Worker }
83*35238bceSAndroid Build Coastguard Worker }
84*35238bceSAndroid Build Coastguard Worker
85*35238bceSAndroid Build Coastguard Worker return true;
86*35238bceSAndroid Build Coastguard Worker }
87*35238bceSAndroid Build Coastguard Worker
readBuffer(const glw::Functions & gl,uint32_t target,int numElements,std::vector<uint32_t> & result)88*35238bceSAndroid Build Coastguard Worker static void readBuffer(const glw::Functions &gl, uint32_t target, int numElements, std::vector<uint32_t> &result)
89*35238bceSAndroid Build Coastguard Worker {
90*35238bceSAndroid Build Coastguard Worker const void *ptr = gl.mapBufferRange(target, 0, (int)(sizeof(uint32_t) * numElements), GL_MAP_READ_BIT);
91*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "map");
92*35238bceSAndroid Build Coastguard Worker
93*35238bceSAndroid Build Coastguard Worker if (!ptr)
94*35238bceSAndroid Build Coastguard Worker throw tcu::TestError("mapBufferRange returned NULL");
95*35238bceSAndroid Build Coastguard Worker
96*35238bceSAndroid Build Coastguard Worker result.resize(numElements);
97*35238bceSAndroid Build Coastguard Worker memcpy(&result[0], ptr, sizeof(uint32_t) * numElements);
98*35238bceSAndroid Build Coastguard Worker
99*35238bceSAndroid Build Coastguard Worker if (gl.unmapBuffer(target) == GL_FALSE)
100*35238bceSAndroid Build Coastguard Worker throw tcu::TestError("unmapBuffer returned false");
101*35238bceSAndroid Build Coastguard Worker }
102*35238bceSAndroid Build Coastguard Worker
readBufferUint32(const glw::Functions & gl,uint32_t target)103*35238bceSAndroid Build Coastguard Worker static uint32_t readBufferUint32(const glw::Functions &gl, uint32_t target)
104*35238bceSAndroid Build Coastguard Worker {
105*35238bceSAndroid Build Coastguard Worker std::vector<uint32_t> vec;
106*35238bceSAndroid Build Coastguard Worker
107*35238bceSAndroid Build Coastguard Worker readBuffer(gl, target, 1, vec);
108*35238bceSAndroid Build Coastguard Worker
109*35238bceSAndroid Build Coastguard Worker return vec[0];
110*35238bceSAndroid Build Coastguard Worker }
111*35238bceSAndroid Build Coastguard Worker
112*35238bceSAndroid Build Coastguard Worker //! Generate a ramp of values from 1 to numElements, and shuffle it
generateShuffledRamp(int numElements,std::vector<int> & ramp)113*35238bceSAndroid Build Coastguard Worker void generateShuffledRamp(int numElements, std::vector<int> &ramp)
114*35238bceSAndroid Build Coastguard Worker {
115*35238bceSAndroid Build Coastguard Worker de::Random rng(0xabcd);
116*35238bceSAndroid Build Coastguard Worker
117*35238bceSAndroid Build Coastguard Worker // some positive (non-zero) unique values
118*35238bceSAndroid Build Coastguard Worker ramp.resize(numElements);
119*35238bceSAndroid Build Coastguard Worker for (int callNdx = 0; callNdx < numElements; ++callNdx)
120*35238bceSAndroid Build Coastguard Worker ramp[callNdx] = callNdx + 1;
121*35238bceSAndroid Build Coastguard Worker
122*35238bceSAndroid Build Coastguard Worker rng.shuffle(ramp.begin(), ramp.end());
123*35238bceSAndroid Build Coastguard Worker }
124*35238bceSAndroid Build Coastguard Worker
specializeShader(Context & context,const char * code)125*35238bceSAndroid Build Coastguard Worker static std::string specializeShader(Context &context, const char *code)
126*35238bceSAndroid Build Coastguard Worker {
127*35238bceSAndroid Build Coastguard Worker auto ctxType = context.getRenderContext().getType();
128*35238bceSAndroid Build Coastguard Worker const bool isES32orGL45 = glu::contextSupports(ctxType, glu::ApiType::es(3, 2)) ||
129*35238bceSAndroid Build Coastguard Worker glu::contextSupports(ctxType, glu::ApiType::core(4, 5));
130*35238bceSAndroid Build Coastguard Worker const glu::GLSLVersion glslVersion = glu::getContextTypeGLSLVersion(ctxType);
131*35238bceSAndroid Build Coastguard Worker
132*35238bceSAndroid Build Coastguard Worker std::map<std::string, std::string> specializationMap;
133*35238bceSAndroid Build Coastguard Worker specializationMap["GLSL_VERSION_DECL"] = glu::getGLSLVersionDeclaration(glslVersion);
134*35238bceSAndroid Build Coastguard Worker specializationMap["SHADER_IMAGE_ATOMIC_REQUIRE"] =
135*35238bceSAndroid Build Coastguard Worker isES32orGL45 ? "" : "#extension GL_OES_shader_image_atomic : require";
136*35238bceSAndroid Build Coastguard Worker
137*35238bceSAndroid Build Coastguard Worker return tcu::StringTemplate(code).specialize(specializationMap);
138*35238bceSAndroid Build Coastguard Worker }
139*35238bceSAndroid Build Coastguard Worker
140*35238bceSAndroid Build Coastguard Worker class InterInvocationTestCase : public TestCase
141*35238bceSAndroid Build Coastguard Worker {
142*35238bceSAndroid Build Coastguard Worker public:
143*35238bceSAndroid Build Coastguard Worker enum StorageType
144*35238bceSAndroid Build Coastguard Worker {
145*35238bceSAndroid Build Coastguard Worker STORAGE_BUFFER = 0,
146*35238bceSAndroid Build Coastguard Worker STORAGE_IMAGE,
147*35238bceSAndroid Build Coastguard Worker
148*35238bceSAndroid Build Coastguard Worker STORAGE_LAST
149*35238bceSAndroid Build Coastguard Worker };
150*35238bceSAndroid Build Coastguard Worker enum CaseFlags
151*35238bceSAndroid Build Coastguard Worker {
152*35238bceSAndroid Build Coastguard Worker FLAG_ATOMIC = 0x1,
153*35238bceSAndroid Build Coastguard Worker FLAG_ALIASING_STORAGES = 0x2,
154*35238bceSAndroid Build Coastguard Worker FLAG_IN_GROUP = 0x4,
155*35238bceSAndroid Build Coastguard Worker };
156*35238bceSAndroid Build Coastguard Worker
157*35238bceSAndroid Build Coastguard Worker InterInvocationTestCase(Context &context, const char *name, const char *desc, StorageType storage, int flags = 0);
158*35238bceSAndroid Build Coastguard Worker ~InterInvocationTestCase(void);
159*35238bceSAndroid Build Coastguard Worker
160*35238bceSAndroid Build Coastguard Worker private:
161*35238bceSAndroid Build Coastguard Worker void init(void);
162*35238bceSAndroid Build Coastguard Worker void deinit(void);
163*35238bceSAndroid Build Coastguard Worker IterateResult iterate(void);
164*35238bceSAndroid Build Coastguard Worker
165*35238bceSAndroid Build Coastguard Worker void runCompute(void);
166*35238bceSAndroid Build Coastguard Worker bool verifyResults(void);
167*35238bceSAndroid Build Coastguard Worker virtual std::string genShaderSource(void) const = 0;
168*35238bceSAndroid Build Coastguard Worker
169*35238bceSAndroid Build Coastguard Worker protected:
170*35238bceSAndroid Build Coastguard Worker std::string genBarrierSource(void) const;
171*35238bceSAndroid Build Coastguard Worker
172*35238bceSAndroid Build Coastguard Worker const StorageType m_storage;
173*35238bceSAndroid Build Coastguard Worker const bool m_useAtomic;
174*35238bceSAndroid Build Coastguard Worker const bool m_aliasingStorages;
175*35238bceSAndroid Build Coastguard Worker const bool m_syncWithGroup;
176*35238bceSAndroid Build Coastguard Worker const int m_workWidth; // !< total work width
177*35238bceSAndroid Build Coastguard Worker const int m_workHeight; // !< ... height
178*35238bceSAndroid Build Coastguard Worker const int m_localWidth; // !< group width
179*35238bceSAndroid Build Coastguard Worker const int m_localHeight; // !< group height
180*35238bceSAndroid Build Coastguard Worker const int m_elementsPerInvocation; // !< elements accessed by a single invocation
181*35238bceSAndroid Build Coastguard Worker
182*35238bceSAndroid Build Coastguard Worker private:
183*35238bceSAndroid Build Coastguard Worker glw::GLuint m_storageBuf;
184*35238bceSAndroid Build Coastguard Worker glw::GLuint m_storageTex;
185*35238bceSAndroid Build Coastguard Worker glw::GLuint m_resultBuf;
186*35238bceSAndroid Build Coastguard Worker glu::ShaderProgram *m_program;
187*35238bceSAndroid Build Coastguard Worker };
188*35238bceSAndroid Build Coastguard Worker
InterInvocationTestCase(Context & context,const char * name,const char * desc,StorageType storage,int flags)189*35238bceSAndroid Build Coastguard Worker InterInvocationTestCase::InterInvocationTestCase(Context &context, const char *name, const char *desc,
190*35238bceSAndroid Build Coastguard Worker StorageType storage, int flags)
191*35238bceSAndroid Build Coastguard Worker : TestCase(context, name, desc)
192*35238bceSAndroid Build Coastguard Worker , m_storage(storage)
193*35238bceSAndroid Build Coastguard Worker , m_useAtomic((flags & FLAG_ATOMIC) != 0)
194*35238bceSAndroid Build Coastguard Worker , m_aliasingStorages((flags & FLAG_ALIASING_STORAGES) != 0)
195*35238bceSAndroid Build Coastguard Worker , m_syncWithGroup((flags & FLAG_IN_GROUP) != 0)
196*35238bceSAndroid Build Coastguard Worker , m_workWidth(256)
197*35238bceSAndroid Build Coastguard Worker , m_workHeight(256)
198*35238bceSAndroid Build Coastguard Worker , m_localWidth(16)
199*35238bceSAndroid Build Coastguard Worker , m_localHeight(8)
200*35238bceSAndroid Build Coastguard Worker , m_elementsPerInvocation(8)
201*35238bceSAndroid Build Coastguard Worker , m_storageBuf(0)
202*35238bceSAndroid Build Coastguard Worker , m_storageTex(0)
203*35238bceSAndroid Build Coastguard Worker , m_resultBuf(0)
204*35238bceSAndroid Build Coastguard Worker , m_program(DE_NULL)
205*35238bceSAndroid Build Coastguard Worker {
206*35238bceSAndroid Build Coastguard Worker DE_ASSERT(m_storage < STORAGE_LAST);
207*35238bceSAndroid Build Coastguard Worker DE_ASSERT(m_localWidth * m_localHeight <= 128); // minimum MAX_COMPUTE_WORK_GROUP_INVOCATIONS value
208*35238bceSAndroid Build Coastguard Worker }
209*35238bceSAndroid Build Coastguard Worker
~InterInvocationTestCase(void)210*35238bceSAndroid Build Coastguard Worker InterInvocationTestCase::~InterInvocationTestCase(void)
211*35238bceSAndroid Build Coastguard Worker {
212*35238bceSAndroid Build Coastguard Worker deinit();
213*35238bceSAndroid Build Coastguard Worker }
214*35238bceSAndroid Build Coastguard Worker
init(void)215*35238bceSAndroid Build Coastguard Worker void InterInvocationTestCase::init(void)
216*35238bceSAndroid Build Coastguard Worker {
217*35238bceSAndroid Build Coastguard Worker const glw::Functions &gl = m_context.getRenderContext().getFunctions();
218*35238bceSAndroid Build Coastguard Worker
219*35238bceSAndroid Build Coastguard Worker // requirements
220*35238bceSAndroid Build Coastguard Worker
221*35238bceSAndroid Build Coastguard Worker if (m_useAtomic && m_storage == STORAGE_IMAGE && !checkSupport(m_context))
222*35238bceSAndroid Build Coastguard Worker throw tcu::NotSupportedError("Test requires GL_OES_shader_image_atomic extension");
223*35238bceSAndroid Build Coastguard Worker
224*35238bceSAndroid Build Coastguard Worker // program
225*35238bceSAndroid Build Coastguard Worker
226*35238bceSAndroid Build Coastguard Worker m_program = new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources()
227*35238bceSAndroid Build Coastguard Worker << glu::ComputeSource(genShaderSource()));
228*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << *m_program;
229*35238bceSAndroid Build Coastguard Worker if (!m_program->isOk())
230*35238bceSAndroid Build Coastguard Worker throw tcu::TestError("could not build program");
231*35238bceSAndroid Build Coastguard Worker
232*35238bceSAndroid Build Coastguard Worker // source
233*35238bceSAndroid Build Coastguard Worker
234*35238bceSAndroid Build Coastguard Worker if (m_storage == STORAGE_BUFFER)
235*35238bceSAndroid Build Coastguard Worker {
236*35238bceSAndroid Build Coastguard Worker const int bufferElements = m_workWidth * m_workHeight * m_elementsPerInvocation;
237*35238bceSAndroid Build Coastguard Worker const int bufferSize = bufferElements * (int)sizeof(uint32_t);
238*35238bceSAndroid Build Coastguard Worker std::vector<uint32_t> zeroBuffer(bufferElements, 0);
239*35238bceSAndroid Build Coastguard Worker
240*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Allocating zero-filled buffer for storage, size "
241*35238bceSAndroid Build Coastguard Worker << bufferElements << " elements, " << bufferSize << " bytes." << tcu::TestLog::EndMessage;
242*35238bceSAndroid Build Coastguard Worker
243*35238bceSAndroid Build Coastguard Worker gl.genBuffers(1, &m_storageBuf);
244*35238bceSAndroid Build Coastguard Worker gl.bindBuffer(GL_SHADER_STORAGE_BUFFER, m_storageBuf);
245*35238bceSAndroid Build Coastguard Worker gl.bufferData(GL_SHADER_STORAGE_BUFFER, bufferSize, &zeroBuffer[0], GL_STATIC_DRAW);
246*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "gen storage buf");
247*35238bceSAndroid Build Coastguard Worker }
248*35238bceSAndroid Build Coastguard Worker else if (m_storage == STORAGE_IMAGE)
249*35238bceSAndroid Build Coastguard Worker {
250*35238bceSAndroid Build Coastguard Worker const int bufferElements = m_workWidth * m_workHeight * m_elementsPerInvocation;
251*35238bceSAndroid Build Coastguard Worker const int bufferSize = bufferElements * (int)sizeof(uint32_t);
252*35238bceSAndroid Build Coastguard Worker
253*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Allocating image for storage, size " << m_workWidth << "x"
254*35238bceSAndroid Build Coastguard Worker << m_workHeight * m_elementsPerInvocation << ", " << bufferSize << " bytes."
255*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
256*35238bceSAndroid Build Coastguard Worker
257*35238bceSAndroid Build Coastguard Worker gl.genTextures(1, &m_storageTex);
258*35238bceSAndroid Build Coastguard Worker gl.bindTexture(GL_TEXTURE_2D, m_storageTex);
259*35238bceSAndroid Build Coastguard Worker gl.texStorage2D(GL_TEXTURE_2D, 1, GL_R32I, m_workWidth, m_workHeight * m_elementsPerInvocation);
260*35238bceSAndroid Build Coastguard Worker gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
261*35238bceSAndroid Build Coastguard Worker gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
262*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "gen storage image");
263*35238bceSAndroid Build Coastguard Worker
264*35238bceSAndroid Build Coastguard Worker // Zero-fill
265*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Filling image with 0." << tcu::TestLog::EndMessage;
266*35238bceSAndroid Build Coastguard Worker
267*35238bceSAndroid Build Coastguard Worker {
268*35238bceSAndroid Build Coastguard Worker const std::vector<int32_t> zeroBuffer(m_workWidth * m_workHeight * m_elementsPerInvocation, 0);
269*35238bceSAndroid Build Coastguard Worker gl.texSubImage2D(GL_TEXTURE_2D, 0, 0, 0, m_workWidth, m_workHeight * m_elementsPerInvocation,
270*35238bceSAndroid Build Coastguard Worker GL_RED_INTEGER, GL_INT, &zeroBuffer[0]);
271*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "specify image contents");
272*35238bceSAndroid Build Coastguard Worker }
273*35238bceSAndroid Build Coastguard Worker }
274*35238bceSAndroid Build Coastguard Worker else
275*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
276*35238bceSAndroid Build Coastguard Worker
277*35238bceSAndroid Build Coastguard Worker // destination
278*35238bceSAndroid Build Coastguard Worker
279*35238bceSAndroid Build Coastguard Worker {
280*35238bceSAndroid Build Coastguard Worker const int bufferElements = m_workWidth * m_workHeight;
281*35238bceSAndroid Build Coastguard Worker const int bufferSize = bufferElements * (int)sizeof(uint32_t);
282*35238bceSAndroid Build Coastguard Worker std::vector<int32_t> negativeBuffer(bufferElements, -1);
283*35238bceSAndroid Build Coastguard Worker
284*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Allocating -1 filled buffer for results, size "
285*35238bceSAndroid Build Coastguard Worker << bufferElements << " elements, " << bufferSize << " bytes." << tcu::TestLog::EndMessage;
286*35238bceSAndroid Build Coastguard Worker
287*35238bceSAndroid Build Coastguard Worker gl.genBuffers(1, &m_resultBuf);
288*35238bceSAndroid Build Coastguard Worker gl.bindBuffer(GL_SHADER_STORAGE_BUFFER, m_resultBuf);
289*35238bceSAndroid Build Coastguard Worker gl.bufferData(GL_SHADER_STORAGE_BUFFER, bufferSize, &negativeBuffer[0], GL_STATIC_DRAW);
290*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "gen storage buf");
291*35238bceSAndroid Build Coastguard Worker }
292*35238bceSAndroid Build Coastguard Worker }
293*35238bceSAndroid Build Coastguard Worker
deinit(void)294*35238bceSAndroid Build Coastguard Worker void InterInvocationTestCase::deinit(void)
295*35238bceSAndroid Build Coastguard Worker {
296*35238bceSAndroid Build Coastguard Worker if (m_storageBuf)
297*35238bceSAndroid Build Coastguard Worker {
298*35238bceSAndroid Build Coastguard Worker m_context.getRenderContext().getFunctions().deleteBuffers(1, &m_storageBuf);
299*35238bceSAndroid Build Coastguard Worker m_storageBuf = DE_NULL;
300*35238bceSAndroid Build Coastguard Worker }
301*35238bceSAndroid Build Coastguard Worker
302*35238bceSAndroid Build Coastguard Worker if (m_storageTex)
303*35238bceSAndroid Build Coastguard Worker {
304*35238bceSAndroid Build Coastguard Worker m_context.getRenderContext().getFunctions().deleteTextures(1, &m_storageTex);
305*35238bceSAndroid Build Coastguard Worker m_storageTex = DE_NULL;
306*35238bceSAndroid Build Coastguard Worker }
307*35238bceSAndroid Build Coastguard Worker
308*35238bceSAndroid Build Coastguard Worker if (m_resultBuf)
309*35238bceSAndroid Build Coastguard Worker {
310*35238bceSAndroid Build Coastguard Worker m_context.getRenderContext().getFunctions().deleteBuffers(1, &m_resultBuf);
311*35238bceSAndroid Build Coastguard Worker m_resultBuf = DE_NULL;
312*35238bceSAndroid Build Coastguard Worker }
313*35238bceSAndroid Build Coastguard Worker
314*35238bceSAndroid Build Coastguard Worker delete m_program;
315*35238bceSAndroid Build Coastguard Worker m_program = DE_NULL;
316*35238bceSAndroid Build Coastguard Worker }
317*35238bceSAndroid Build Coastguard Worker
iterate(void)318*35238bceSAndroid Build Coastguard Worker InterInvocationTestCase::IterateResult InterInvocationTestCase::iterate(void)
319*35238bceSAndroid Build Coastguard Worker {
320*35238bceSAndroid Build Coastguard Worker // Dispatch
321*35238bceSAndroid Build Coastguard Worker runCompute();
322*35238bceSAndroid Build Coastguard Worker
323*35238bceSAndroid Build Coastguard Worker // Verify buffer contents
324*35238bceSAndroid Build Coastguard Worker if (verifyResults())
325*35238bceSAndroid Build Coastguard Worker m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
326*35238bceSAndroid Build Coastguard Worker else
327*35238bceSAndroid Build Coastguard Worker m_testCtx.setTestResult(
328*35238bceSAndroid Build Coastguard Worker QP_TEST_RESULT_FAIL,
329*35238bceSAndroid Build Coastguard Worker (std::string((m_storage == STORAGE_BUFFER) ? ("buffer") : ("image")) + " content verification failed")
330*35238bceSAndroid Build Coastguard Worker .c_str());
331*35238bceSAndroid Build Coastguard Worker
332*35238bceSAndroid Build Coastguard Worker return STOP;
333*35238bceSAndroid Build Coastguard Worker }
334*35238bceSAndroid Build Coastguard Worker
runCompute(void)335*35238bceSAndroid Build Coastguard Worker void InterInvocationTestCase::runCompute(void)
336*35238bceSAndroid Build Coastguard Worker {
337*35238bceSAndroid Build Coastguard Worker const glw::Functions &gl = m_context.getRenderContext().getFunctions();
338*35238bceSAndroid Build Coastguard Worker const int groupsX = m_workWidth / m_localWidth;
339*35238bceSAndroid Build Coastguard Worker const int groupsY = m_workHeight / m_localHeight;
340*35238bceSAndroid Build Coastguard Worker
341*35238bceSAndroid Build Coastguard Worker DE_ASSERT((m_workWidth % m_localWidth) == 0);
342*35238bceSAndroid Build Coastguard Worker DE_ASSERT((m_workHeight % m_localHeight) == 0);
343*35238bceSAndroid Build Coastguard Worker
344*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Dispatching compute.\n"
345*35238bceSAndroid Build Coastguard Worker << " group size: " << m_localWidth << "x" << m_localHeight << "\n"
346*35238bceSAndroid Build Coastguard Worker << " dispatch size: " << groupsX << "x" << groupsY << "\n"
347*35238bceSAndroid Build Coastguard Worker << " total work size: " << m_workWidth << "x" << m_workHeight << "\n"
348*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
349*35238bceSAndroid Build Coastguard Worker
350*35238bceSAndroid Build Coastguard Worker gl.useProgram(m_program->getProgram());
351*35238bceSAndroid Build Coastguard Worker
352*35238bceSAndroid Build Coastguard Worker // source
353*35238bceSAndroid Build Coastguard Worker if (m_storage == STORAGE_BUFFER && !m_aliasingStorages)
354*35238bceSAndroid Build Coastguard Worker {
355*35238bceSAndroid Build Coastguard Worker gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_storageBuf);
356*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "bind source buf");
357*35238bceSAndroid Build Coastguard Worker }
358*35238bceSAndroid Build Coastguard Worker else if (m_storage == STORAGE_BUFFER && m_aliasingStorages)
359*35238bceSAndroid Build Coastguard Worker {
360*35238bceSAndroid Build Coastguard Worker gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_storageBuf);
361*35238bceSAndroid Build Coastguard Worker gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, m_storageBuf);
362*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "bind source buf");
363*35238bceSAndroid Build Coastguard Worker
364*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Binding same buffer object to buffer storages."
365*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
366*35238bceSAndroid Build Coastguard Worker }
367*35238bceSAndroid Build Coastguard Worker else if (m_storage == STORAGE_IMAGE && !m_aliasingStorages)
368*35238bceSAndroid Build Coastguard Worker {
369*35238bceSAndroid Build Coastguard Worker gl.bindImageTexture(1, m_storageTex, 0, GL_FALSE, 0, GL_READ_WRITE, GL_R32I);
370*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "bind result buf");
371*35238bceSAndroid Build Coastguard Worker }
372*35238bceSAndroid Build Coastguard Worker else if (m_storage == STORAGE_IMAGE && m_aliasingStorages)
373*35238bceSAndroid Build Coastguard Worker {
374*35238bceSAndroid Build Coastguard Worker gl.bindImageTexture(1, m_storageTex, 0, GL_FALSE, 0, GL_READ_WRITE, GL_R32I);
375*35238bceSAndroid Build Coastguard Worker gl.bindImageTexture(2, m_storageTex, 0, GL_FALSE, 0, GL_READ_WRITE, GL_R32I);
376*35238bceSAndroid Build Coastguard Worker
377*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "bind result buf");
378*35238bceSAndroid Build Coastguard Worker
379*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Binding same texture level to image storages."
380*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
381*35238bceSAndroid Build Coastguard Worker }
382*35238bceSAndroid Build Coastguard Worker else
383*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
384*35238bceSAndroid Build Coastguard Worker
385*35238bceSAndroid Build Coastguard Worker // destination
386*35238bceSAndroid Build Coastguard Worker gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_resultBuf);
387*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "bind result buf");
388*35238bceSAndroid Build Coastguard Worker
389*35238bceSAndroid Build Coastguard Worker // dispatch
390*35238bceSAndroid Build Coastguard Worker gl.dispatchCompute(groupsX, groupsY, 1);
391*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "dispatchCompute");
392*35238bceSAndroid Build Coastguard Worker }
393*35238bceSAndroid Build Coastguard Worker
verifyResults(void)394*35238bceSAndroid Build Coastguard Worker bool InterInvocationTestCase::verifyResults(void)
395*35238bceSAndroid Build Coastguard Worker {
396*35238bceSAndroid Build Coastguard Worker const glw::Functions &gl = m_context.getRenderContext().getFunctions();
397*35238bceSAndroid Build Coastguard Worker const int errorFloodThreshold = 5;
398*35238bceSAndroid Build Coastguard Worker int numErrorsLogged = 0;
399*35238bceSAndroid Build Coastguard Worker const void *mapped = DE_NULL;
400*35238bceSAndroid Build Coastguard Worker std::vector<int32_t> results(m_workWidth * m_workHeight);
401*35238bceSAndroid Build Coastguard Worker bool error = false;
402*35238bceSAndroid Build Coastguard Worker
403*35238bceSAndroid Build Coastguard Worker gl.bindBuffer(GL_SHADER_STORAGE_BUFFER, m_resultBuf);
404*35238bceSAndroid Build Coastguard Worker gl.memoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
405*35238bceSAndroid Build Coastguard Worker mapped =
406*35238bceSAndroid Build Coastguard Worker gl.mapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, m_workWidth * m_workHeight * sizeof(int32_t), GL_MAP_READ_BIT);
407*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "map buffer");
408*35238bceSAndroid Build Coastguard Worker
409*35238bceSAndroid Build Coastguard Worker // copy to properly aligned array
410*35238bceSAndroid Build Coastguard Worker deMemcpy(&results[0], mapped, m_workWidth * m_workHeight * sizeof(uint32_t));
411*35238bceSAndroid Build Coastguard Worker
412*35238bceSAndroid Build Coastguard Worker if (gl.unmapBuffer(GL_SHADER_STORAGE_BUFFER) != GL_TRUE)
413*35238bceSAndroid Build Coastguard Worker throw tcu::TestError("memory map store corrupted");
414*35238bceSAndroid Build Coastguard Worker
415*35238bceSAndroid Build Coastguard Worker // check the results
416*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < (int)results.size(); ++ndx)
417*35238bceSAndroid Build Coastguard Worker {
418*35238bceSAndroid Build Coastguard Worker if (results[ndx] != 1)
419*35238bceSAndroid Build Coastguard Worker {
420*35238bceSAndroid Build Coastguard Worker error = true;
421*35238bceSAndroid Build Coastguard Worker
422*35238bceSAndroid Build Coastguard Worker if (numErrorsLogged == 0)
423*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Result buffer failed, got unexpected values.\n"
424*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
425*35238bceSAndroid Build Coastguard Worker if (numErrorsLogged++ < errorFloodThreshold)
426*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << " Error at index " << ndx << ": expected 1, got "
427*35238bceSAndroid Build Coastguard Worker << results[ndx] << ".\n"
428*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
429*35238bceSAndroid Build Coastguard Worker else
430*35238bceSAndroid Build Coastguard Worker {
431*35238bceSAndroid Build Coastguard Worker // after N errors, no point continuing verification
432*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << " -- too many errors, skipping verification --\n"
433*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
434*35238bceSAndroid Build Coastguard Worker break;
435*35238bceSAndroid Build Coastguard Worker }
436*35238bceSAndroid Build Coastguard Worker }
437*35238bceSAndroid Build Coastguard Worker }
438*35238bceSAndroid Build Coastguard Worker
439*35238bceSAndroid Build Coastguard Worker if (!error)
440*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Result buffer ok." << tcu::TestLog::EndMessage;
441*35238bceSAndroid Build Coastguard Worker return !error;
442*35238bceSAndroid Build Coastguard Worker }
443*35238bceSAndroid Build Coastguard Worker
genBarrierSource(void) const444*35238bceSAndroid Build Coastguard Worker std::string InterInvocationTestCase::genBarrierSource(void) const
445*35238bceSAndroid Build Coastguard Worker {
446*35238bceSAndroid Build Coastguard Worker std::ostringstream buf;
447*35238bceSAndroid Build Coastguard Worker
448*35238bceSAndroid Build Coastguard Worker if (m_syncWithGroup)
449*35238bceSAndroid Build Coastguard Worker {
450*35238bceSAndroid Build Coastguard Worker // Wait until all invocations in this work group have their texture/buffer read/write operations complete
451*35238bceSAndroid Build Coastguard Worker // \note We could also use memoryBarrierBuffer() or memoryBarrierImage() in place of groupMemoryBarrier() but
452*35238bceSAndroid Build Coastguard Worker // we only require intra-workgroup synchronization.
453*35238bceSAndroid Build Coastguard Worker buf << "\n"
454*35238bceSAndroid Build Coastguard Worker << " groupMemoryBarrier();\n"
455*35238bceSAndroid Build Coastguard Worker << " barrier();\n"
456*35238bceSAndroid Build Coastguard Worker << "\n";
457*35238bceSAndroid Build Coastguard Worker }
458*35238bceSAndroid Build Coastguard Worker else if (m_storage == STORAGE_BUFFER)
459*35238bceSAndroid Build Coastguard Worker {
460*35238bceSAndroid Build Coastguard Worker DE_ASSERT(!m_syncWithGroup);
461*35238bceSAndroid Build Coastguard Worker
462*35238bceSAndroid Build Coastguard Worker // Waiting only for data written by this invocation. Since all buffer reads and writes are
463*35238bceSAndroid Build Coastguard Worker // processed in order (within a single invocation), we don't have to do anything.
464*35238bceSAndroid Build Coastguard Worker buf << "\n";
465*35238bceSAndroid Build Coastguard Worker }
466*35238bceSAndroid Build Coastguard Worker else if (m_storage == STORAGE_IMAGE)
467*35238bceSAndroid Build Coastguard Worker {
468*35238bceSAndroid Build Coastguard Worker DE_ASSERT(!m_syncWithGroup);
469*35238bceSAndroid Build Coastguard Worker
470*35238bceSAndroid Build Coastguard Worker // Waiting only for data written by this invocation. But since operations complete in undefined
471*35238bceSAndroid Build Coastguard Worker // order, we have to wait for them to complete.
472*35238bceSAndroid Build Coastguard Worker buf << "\n"
473*35238bceSAndroid Build Coastguard Worker << " memoryBarrierImage();\n"
474*35238bceSAndroid Build Coastguard Worker << "\n";
475*35238bceSAndroid Build Coastguard Worker }
476*35238bceSAndroid Build Coastguard Worker else
477*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
478*35238bceSAndroid Build Coastguard Worker
479*35238bceSAndroid Build Coastguard Worker return buf.str();
480*35238bceSAndroid Build Coastguard Worker }
481*35238bceSAndroid Build Coastguard Worker
482*35238bceSAndroid Build Coastguard Worker class InvocationBasicCase : public InterInvocationTestCase
483*35238bceSAndroid Build Coastguard Worker {
484*35238bceSAndroid Build Coastguard Worker public:
485*35238bceSAndroid Build Coastguard Worker InvocationBasicCase(Context &context, const char *name, const char *desc, StorageType storage, int flags);
486*35238bceSAndroid Build Coastguard Worker
487*35238bceSAndroid Build Coastguard Worker private:
488*35238bceSAndroid Build Coastguard Worker std::string genShaderSource(void) const;
489*35238bceSAndroid Build Coastguard Worker virtual std::string genShaderMainBlock(void) const = 0;
490*35238bceSAndroid Build Coastguard Worker };
491*35238bceSAndroid Build Coastguard Worker
InvocationBasicCase(Context & context,const char * name,const char * desc,StorageType storage,int flags)492*35238bceSAndroid Build Coastguard Worker InvocationBasicCase::InvocationBasicCase(Context &context, const char *name, const char *desc, StorageType storage,
493*35238bceSAndroid Build Coastguard Worker int flags)
494*35238bceSAndroid Build Coastguard Worker : InterInvocationTestCase(context, name, desc, storage, flags)
495*35238bceSAndroid Build Coastguard Worker {
496*35238bceSAndroid Build Coastguard Worker }
497*35238bceSAndroid Build Coastguard Worker
genShaderSource(void) const498*35238bceSAndroid Build Coastguard Worker std::string InvocationBasicCase::genShaderSource(void) const
499*35238bceSAndroid Build Coastguard Worker {
500*35238bceSAndroid Build Coastguard Worker const bool useImageAtomics = m_useAtomic && m_storage == STORAGE_IMAGE;
501*35238bceSAndroid Build Coastguard Worker std::ostringstream buf;
502*35238bceSAndroid Build Coastguard Worker
503*35238bceSAndroid Build Coastguard Worker buf << "${GLSL_VERSION_DECL}\n"
504*35238bceSAndroid Build Coastguard Worker << ((useImageAtomics) ? ("${SHADER_IMAGE_ATOMIC_REQUIRE}\n") : ("")) << "layout (local_size_x=" << m_localWidth
505*35238bceSAndroid Build Coastguard Worker << ", local_size_y=" << m_localHeight << ") in;\n"
506*35238bceSAndroid Build Coastguard Worker << "layout(binding=0, std430) buffer Output\n"
507*35238bceSAndroid Build Coastguard Worker << "{\n"
508*35238bceSAndroid Build Coastguard Worker << " highp int values[];\n"
509*35238bceSAndroid Build Coastguard Worker << "} sb_result;\n";
510*35238bceSAndroid Build Coastguard Worker
511*35238bceSAndroid Build Coastguard Worker if (m_storage == STORAGE_BUFFER)
512*35238bceSAndroid Build Coastguard Worker buf << "layout(binding=1, std430) coherent buffer Storage\n"
513*35238bceSAndroid Build Coastguard Worker << "{\n"
514*35238bceSAndroid Build Coastguard Worker << " highp int values[];\n"
515*35238bceSAndroid Build Coastguard Worker << "} sb_store;\n"
516*35238bceSAndroid Build Coastguard Worker << "\n"
517*35238bceSAndroid Build Coastguard Worker << "highp int getIndex (in highp uvec2 localID, in highp int element)\n"
518*35238bceSAndroid Build Coastguard Worker << "{\n"
519*35238bceSAndroid Build Coastguard Worker << " highp uint groupNdx = gl_NumWorkGroups.x * gl_WorkGroupID.y + gl_WorkGroupID.x;\n"
520*35238bceSAndroid Build Coastguard Worker << " return int((localID.y * gl_NumWorkGroups.x * gl_NumWorkGroups.y * gl_WorkGroupSize.x) + (groupNdx "
521*35238bceSAndroid Build Coastguard Worker "* gl_WorkGroupSize.x) + localID.x) * "
522*35238bceSAndroid Build Coastguard Worker << m_elementsPerInvocation << " + element;\n"
523*35238bceSAndroid Build Coastguard Worker << "}\n";
524*35238bceSAndroid Build Coastguard Worker else if (m_storage == STORAGE_IMAGE)
525*35238bceSAndroid Build Coastguard Worker buf << "layout(r32i, binding=1) coherent uniform highp iimage2D u_image;\n"
526*35238bceSAndroid Build Coastguard Worker << "\n"
527*35238bceSAndroid Build Coastguard Worker << "highp ivec2 getCoord (in highp uvec2 localID, in highp int element)\n"
528*35238bceSAndroid Build Coastguard Worker << "{\n"
529*35238bceSAndroid Build Coastguard Worker << " return ivec2(int(gl_WorkGroupID.x * gl_WorkGroupSize.x + localID.x), int(gl_WorkGroupID.y * "
530*35238bceSAndroid Build Coastguard Worker "gl_WorkGroupSize.y + localID.y) + element * "
531*35238bceSAndroid Build Coastguard Worker << m_workHeight << ");\n"
532*35238bceSAndroid Build Coastguard Worker << "}\n";
533*35238bceSAndroid Build Coastguard Worker else
534*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
535*35238bceSAndroid Build Coastguard Worker
536*35238bceSAndroid Build Coastguard Worker buf << "\n"
537*35238bceSAndroid Build Coastguard Worker << "void main (void)\n"
538*35238bceSAndroid Build Coastguard Worker << "{\n"
539*35238bceSAndroid Build Coastguard Worker << " int resultNdx = int(gl_GlobalInvocationID.y * gl_NumWorkGroups.x * gl_WorkGroupSize.x + "
540*35238bceSAndroid Build Coastguard Worker "gl_GlobalInvocationID.x);\n"
541*35238bceSAndroid Build Coastguard Worker << " int groupNdx = int(gl_NumWorkGroups.x * gl_WorkGroupID.y + gl_WorkGroupID.x);\n"
542*35238bceSAndroid Build Coastguard Worker << " bool allOk = true;\n"
543*35238bceSAndroid Build Coastguard Worker << "\n"
544*35238bceSAndroid Build Coastguard Worker << genShaderMainBlock() << "\n"
545*35238bceSAndroid Build Coastguard Worker << " sb_result.values[resultNdx] = (allOk) ? (1) : (0);\n"
546*35238bceSAndroid Build Coastguard Worker << "}\n";
547*35238bceSAndroid Build Coastguard Worker
548*35238bceSAndroid Build Coastguard Worker return specializeShader(m_context, buf.str().c_str());
549*35238bceSAndroid Build Coastguard Worker }
550*35238bceSAndroid Build Coastguard Worker
551*35238bceSAndroid Build Coastguard Worker class InvocationWriteReadCase : public InvocationBasicCase
552*35238bceSAndroid Build Coastguard Worker {
553*35238bceSAndroid Build Coastguard Worker public:
554*35238bceSAndroid Build Coastguard Worker InvocationWriteReadCase(Context &context, const char *name, const char *desc, StorageType storage, int flags);
555*35238bceSAndroid Build Coastguard Worker
556*35238bceSAndroid Build Coastguard Worker private:
557*35238bceSAndroid Build Coastguard Worker std::string genShaderMainBlock(void) const;
558*35238bceSAndroid Build Coastguard Worker };
559*35238bceSAndroid Build Coastguard Worker
InvocationWriteReadCase(Context & context,const char * name,const char * desc,StorageType storage,int flags)560*35238bceSAndroid Build Coastguard Worker InvocationWriteReadCase::InvocationWriteReadCase(Context &context, const char *name, const char *desc,
561*35238bceSAndroid Build Coastguard Worker StorageType storage, int flags)
562*35238bceSAndroid Build Coastguard Worker : InvocationBasicCase(context, name, desc, storage, flags)
563*35238bceSAndroid Build Coastguard Worker {
564*35238bceSAndroid Build Coastguard Worker }
565*35238bceSAndroid Build Coastguard Worker
genShaderMainBlock(void) const566*35238bceSAndroid Build Coastguard Worker std::string InvocationWriteReadCase::genShaderMainBlock(void) const
567*35238bceSAndroid Build Coastguard Worker {
568*35238bceSAndroid Build Coastguard Worker std::ostringstream buf;
569*35238bceSAndroid Build Coastguard Worker
570*35238bceSAndroid Build Coastguard Worker // write
571*35238bceSAndroid Build Coastguard Worker
572*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < m_elementsPerInvocation; ++ndx)
573*35238bceSAndroid Build Coastguard Worker {
574*35238bceSAndroid Build Coastguard Worker if (m_storage == STORAGE_BUFFER && m_useAtomic)
575*35238bceSAndroid Build Coastguard Worker buf << "\tatomicAdd(sb_store.values[getIndex(gl_LocalInvocationID.xy, " << ndx << ")], groupNdx);\n";
576*35238bceSAndroid Build Coastguard Worker else if (m_storage == STORAGE_BUFFER && !m_useAtomic)
577*35238bceSAndroid Build Coastguard Worker buf << "\tsb_store.values[getIndex(gl_LocalInvocationID.xy, " << ndx << ")] = groupNdx;\n";
578*35238bceSAndroid Build Coastguard Worker else if (m_storage == STORAGE_IMAGE && m_useAtomic)
579*35238bceSAndroid Build Coastguard Worker buf << "\timageAtomicAdd(u_image, getCoord(gl_LocalInvocationID.xy, " << ndx << "), int(groupNdx));\n";
580*35238bceSAndroid Build Coastguard Worker else if (m_storage == STORAGE_IMAGE && !m_useAtomic)
581*35238bceSAndroid Build Coastguard Worker buf << "\timageStore(u_image, getCoord(gl_LocalInvocationID.xy, " << ndx
582*35238bceSAndroid Build Coastguard Worker << "), ivec4(int(groupNdx), 0, 0, 0));\n";
583*35238bceSAndroid Build Coastguard Worker else
584*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
585*35238bceSAndroid Build Coastguard Worker }
586*35238bceSAndroid Build Coastguard Worker
587*35238bceSAndroid Build Coastguard Worker // barrier
588*35238bceSAndroid Build Coastguard Worker
589*35238bceSAndroid Build Coastguard Worker buf << genBarrierSource();
590*35238bceSAndroid Build Coastguard Worker
591*35238bceSAndroid Build Coastguard Worker // read
592*35238bceSAndroid Build Coastguard Worker
593*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < m_elementsPerInvocation; ++ndx)
594*35238bceSAndroid Build Coastguard Worker {
595*35238bceSAndroid Build Coastguard Worker const std::string localID = (m_syncWithGroup) ? ("(gl_LocalInvocationID.xy + uvec2(" + de::toString(ndx + 1) +
596*35238bceSAndroid Build Coastguard Worker ", " + de::toString(2 * ndx) + ")) % gl_WorkGroupSize.xy") :
597*35238bceSAndroid Build Coastguard Worker ("gl_LocalInvocationID.xy");
598*35238bceSAndroid Build Coastguard Worker
599*35238bceSAndroid Build Coastguard Worker if (m_storage == STORAGE_BUFFER && m_useAtomic)
600*35238bceSAndroid Build Coastguard Worker buf << "\tallOk = allOk && (atomicExchange(sb_store.values[getIndex(" << localID << ", " << ndx
601*35238bceSAndroid Build Coastguard Worker << ")], 0) == groupNdx);\n";
602*35238bceSAndroid Build Coastguard Worker else if (m_storage == STORAGE_BUFFER && !m_useAtomic)
603*35238bceSAndroid Build Coastguard Worker buf << "\tallOk = allOk && (sb_store.values[getIndex(" << localID << ", " << ndx << ")] == groupNdx);\n";
604*35238bceSAndroid Build Coastguard Worker else if (m_storage == STORAGE_IMAGE && m_useAtomic)
605*35238bceSAndroid Build Coastguard Worker buf << "\tallOk = allOk && (imageAtomicExchange(u_image, getCoord(" << localID << ", " << ndx
606*35238bceSAndroid Build Coastguard Worker << "), 0) == groupNdx);\n";
607*35238bceSAndroid Build Coastguard Worker else if (m_storage == STORAGE_IMAGE && !m_useAtomic)
608*35238bceSAndroid Build Coastguard Worker buf << "\tallOk = allOk && (imageLoad(u_image, getCoord(" << localID << ", " << ndx
609*35238bceSAndroid Build Coastguard Worker << ")).x == groupNdx);\n";
610*35238bceSAndroid Build Coastguard Worker else
611*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
612*35238bceSAndroid Build Coastguard Worker }
613*35238bceSAndroid Build Coastguard Worker
614*35238bceSAndroid Build Coastguard Worker return buf.str();
615*35238bceSAndroid Build Coastguard Worker }
616*35238bceSAndroid Build Coastguard Worker
617*35238bceSAndroid Build Coastguard Worker class InvocationReadWriteCase : public InvocationBasicCase
618*35238bceSAndroid Build Coastguard Worker {
619*35238bceSAndroid Build Coastguard Worker public:
620*35238bceSAndroid Build Coastguard Worker InvocationReadWriteCase(Context &context, const char *name, const char *desc, StorageType storage, int flags);
621*35238bceSAndroid Build Coastguard Worker
622*35238bceSAndroid Build Coastguard Worker private:
623*35238bceSAndroid Build Coastguard Worker std::string genShaderMainBlock(void) const;
624*35238bceSAndroid Build Coastguard Worker };
625*35238bceSAndroid Build Coastguard Worker
InvocationReadWriteCase(Context & context,const char * name,const char * desc,StorageType storage,int flags)626*35238bceSAndroid Build Coastguard Worker InvocationReadWriteCase::InvocationReadWriteCase(Context &context, const char *name, const char *desc,
627*35238bceSAndroid Build Coastguard Worker StorageType storage, int flags)
628*35238bceSAndroid Build Coastguard Worker : InvocationBasicCase(context, name, desc, storage, flags)
629*35238bceSAndroid Build Coastguard Worker {
630*35238bceSAndroid Build Coastguard Worker }
631*35238bceSAndroid Build Coastguard Worker
genShaderMainBlock(void) const632*35238bceSAndroid Build Coastguard Worker std::string InvocationReadWriteCase::genShaderMainBlock(void) const
633*35238bceSAndroid Build Coastguard Worker {
634*35238bceSAndroid Build Coastguard Worker std::ostringstream buf;
635*35238bceSAndroid Build Coastguard Worker
636*35238bceSAndroid Build Coastguard Worker // read
637*35238bceSAndroid Build Coastguard Worker
638*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < m_elementsPerInvocation; ++ndx)
639*35238bceSAndroid Build Coastguard Worker {
640*35238bceSAndroid Build Coastguard Worker const std::string localID = (m_syncWithGroup) ? ("(gl_LocalInvocationID.xy + uvec2(" + de::toString(ndx + 1) +
641*35238bceSAndroid Build Coastguard Worker ", " + de::toString(2 * ndx) + ")) % gl_WorkGroupSize.xy") :
642*35238bceSAndroid Build Coastguard Worker ("gl_LocalInvocationID.xy");
643*35238bceSAndroid Build Coastguard Worker
644*35238bceSAndroid Build Coastguard Worker if (m_storage == STORAGE_BUFFER && m_useAtomic)
645*35238bceSAndroid Build Coastguard Worker buf << "\tallOk = allOk && (atomicExchange(sb_store.values[getIndex(" << localID << ", " << ndx
646*35238bceSAndroid Build Coastguard Worker << ")], 123) == 0);\n";
647*35238bceSAndroid Build Coastguard Worker else if (m_storage == STORAGE_BUFFER && !m_useAtomic)
648*35238bceSAndroid Build Coastguard Worker buf << "\tallOk = allOk && (sb_store.values[getIndex(" << localID << ", " << ndx << ")] == 0);\n";
649*35238bceSAndroid Build Coastguard Worker else if (m_storage == STORAGE_IMAGE && m_useAtomic)
650*35238bceSAndroid Build Coastguard Worker buf << "\tallOk = allOk && (imageAtomicExchange(u_image, getCoord(" << localID << ", " << ndx
651*35238bceSAndroid Build Coastguard Worker << "), 123) == 0);\n";
652*35238bceSAndroid Build Coastguard Worker else if (m_storage == STORAGE_IMAGE && !m_useAtomic)
653*35238bceSAndroid Build Coastguard Worker buf << "\tallOk = allOk && (imageLoad(u_image, getCoord(" << localID << ", " << ndx << ")).x == 0);\n";
654*35238bceSAndroid Build Coastguard Worker else
655*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
656*35238bceSAndroid Build Coastguard Worker }
657*35238bceSAndroid Build Coastguard Worker
658*35238bceSAndroid Build Coastguard Worker // barrier
659*35238bceSAndroid Build Coastguard Worker
660*35238bceSAndroid Build Coastguard Worker buf << genBarrierSource();
661*35238bceSAndroid Build Coastguard Worker
662*35238bceSAndroid Build Coastguard Worker // write
663*35238bceSAndroid Build Coastguard Worker
664*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < m_elementsPerInvocation; ++ndx)
665*35238bceSAndroid Build Coastguard Worker {
666*35238bceSAndroid Build Coastguard Worker if (m_storage == STORAGE_BUFFER && m_useAtomic)
667*35238bceSAndroid Build Coastguard Worker buf << "\tatomicAdd(sb_store.values[getIndex(gl_LocalInvocationID.xy, " << ndx << ")], groupNdx);\n";
668*35238bceSAndroid Build Coastguard Worker else if (m_storage == STORAGE_BUFFER && !m_useAtomic)
669*35238bceSAndroid Build Coastguard Worker buf << "\tsb_store.values[getIndex(gl_LocalInvocationID.xy, " << ndx << ")] = groupNdx;\n";
670*35238bceSAndroid Build Coastguard Worker else if (m_storage == STORAGE_IMAGE && m_useAtomic)
671*35238bceSAndroid Build Coastguard Worker buf << "\timageAtomicAdd(u_image, getCoord(gl_LocalInvocationID.xy, " << ndx << "), int(groupNdx));\n";
672*35238bceSAndroid Build Coastguard Worker else if (m_storage == STORAGE_IMAGE && !m_useAtomic)
673*35238bceSAndroid Build Coastguard Worker buf << "\timageStore(u_image, getCoord(gl_LocalInvocationID.xy, " << ndx
674*35238bceSAndroid Build Coastguard Worker << "), ivec4(int(groupNdx), 0, 0, 0));\n";
675*35238bceSAndroid Build Coastguard Worker else
676*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
677*35238bceSAndroid Build Coastguard Worker }
678*35238bceSAndroid Build Coastguard Worker
679*35238bceSAndroid Build Coastguard Worker return buf.str();
680*35238bceSAndroid Build Coastguard Worker }
681*35238bceSAndroid Build Coastguard Worker
682*35238bceSAndroid Build Coastguard Worker class InvocationOverWriteCase : public InvocationBasicCase
683*35238bceSAndroid Build Coastguard Worker {
684*35238bceSAndroid Build Coastguard Worker public:
685*35238bceSAndroid Build Coastguard Worker InvocationOverWriteCase(Context &context, const char *name, const char *desc, StorageType storage, int flags);
686*35238bceSAndroid Build Coastguard Worker
687*35238bceSAndroid Build Coastguard Worker private:
688*35238bceSAndroid Build Coastguard Worker std::string genShaderMainBlock(void) const;
689*35238bceSAndroid Build Coastguard Worker };
690*35238bceSAndroid Build Coastguard Worker
InvocationOverWriteCase(Context & context,const char * name,const char * desc,StorageType storage,int flags)691*35238bceSAndroid Build Coastguard Worker InvocationOverWriteCase::InvocationOverWriteCase(Context &context, const char *name, const char *desc,
692*35238bceSAndroid Build Coastguard Worker StorageType storage, int flags)
693*35238bceSAndroid Build Coastguard Worker : InvocationBasicCase(context, name, desc, storage, flags)
694*35238bceSAndroid Build Coastguard Worker {
695*35238bceSAndroid Build Coastguard Worker }
696*35238bceSAndroid Build Coastguard Worker
genShaderMainBlock(void) const697*35238bceSAndroid Build Coastguard Worker std::string InvocationOverWriteCase::genShaderMainBlock(void) const
698*35238bceSAndroid Build Coastguard Worker {
699*35238bceSAndroid Build Coastguard Worker std::ostringstream buf;
700*35238bceSAndroid Build Coastguard Worker
701*35238bceSAndroid Build Coastguard Worker // write
702*35238bceSAndroid Build Coastguard Worker
703*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < m_elementsPerInvocation; ++ndx)
704*35238bceSAndroid Build Coastguard Worker {
705*35238bceSAndroid Build Coastguard Worker if (m_storage == STORAGE_BUFFER && m_useAtomic)
706*35238bceSAndroid Build Coastguard Worker buf << "\tatomicAdd(sb_store.values[getIndex(gl_LocalInvocationID.xy, " << ndx << ")], 456);\n";
707*35238bceSAndroid Build Coastguard Worker else if (m_storage == STORAGE_BUFFER && !m_useAtomic)
708*35238bceSAndroid Build Coastguard Worker buf << "\tsb_store.values[getIndex(gl_LocalInvocationID.xy, " << ndx << ")] = 456;\n";
709*35238bceSAndroid Build Coastguard Worker else if (m_storage == STORAGE_IMAGE && m_useAtomic)
710*35238bceSAndroid Build Coastguard Worker buf << "\timageAtomicAdd(u_image, getCoord(gl_LocalInvocationID.xy, " << ndx << "), 456);\n";
711*35238bceSAndroid Build Coastguard Worker else if (m_storage == STORAGE_IMAGE && !m_useAtomic)
712*35238bceSAndroid Build Coastguard Worker buf << "\timageStore(u_image, getCoord(gl_LocalInvocationID.xy, " << ndx << "), ivec4(456, 0, 0, 0));\n";
713*35238bceSAndroid Build Coastguard Worker else
714*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
715*35238bceSAndroid Build Coastguard Worker }
716*35238bceSAndroid Build Coastguard Worker
717*35238bceSAndroid Build Coastguard Worker // barrier
718*35238bceSAndroid Build Coastguard Worker
719*35238bceSAndroid Build Coastguard Worker buf << genBarrierSource();
720*35238bceSAndroid Build Coastguard Worker
721*35238bceSAndroid Build Coastguard Worker // write over
722*35238bceSAndroid Build Coastguard Worker
723*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < m_elementsPerInvocation; ++ndx)
724*35238bceSAndroid Build Coastguard Worker {
725*35238bceSAndroid Build Coastguard Worker // write another invocation's value or our own value depending on test type
726*35238bceSAndroid Build Coastguard Worker const std::string localID = (m_syncWithGroup) ? ("(gl_LocalInvocationID.xy + uvec2(" + de::toString(ndx + 4) +
727*35238bceSAndroid Build Coastguard Worker ", " + de::toString(3 * ndx) + ")) % gl_WorkGroupSize.xy") :
728*35238bceSAndroid Build Coastguard Worker ("gl_LocalInvocationID.xy");
729*35238bceSAndroid Build Coastguard Worker
730*35238bceSAndroid Build Coastguard Worker if (m_storage == STORAGE_BUFFER && m_useAtomic)
731*35238bceSAndroid Build Coastguard Worker buf << "\tatomicExchange(sb_store.values[getIndex(" << localID << ", " << ndx << ")], groupNdx);\n";
732*35238bceSAndroid Build Coastguard Worker else if (m_storage == STORAGE_BUFFER && !m_useAtomic)
733*35238bceSAndroid Build Coastguard Worker buf << "\tsb_store.values[getIndex(" << localID << ", " << ndx << ")] = groupNdx;\n";
734*35238bceSAndroid Build Coastguard Worker else if (m_storage == STORAGE_IMAGE && m_useAtomic)
735*35238bceSAndroid Build Coastguard Worker buf << "\timageAtomicExchange(u_image, getCoord(" << localID << ", " << ndx << "), groupNdx);\n";
736*35238bceSAndroid Build Coastguard Worker else if (m_storage == STORAGE_IMAGE && !m_useAtomic)
737*35238bceSAndroid Build Coastguard Worker buf << "\timageStore(u_image, getCoord(" << localID << ", " << ndx << "), ivec4(groupNdx, 0, 0, 0));\n";
738*35238bceSAndroid Build Coastguard Worker else
739*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
740*35238bceSAndroid Build Coastguard Worker }
741*35238bceSAndroid Build Coastguard Worker
742*35238bceSAndroid Build Coastguard Worker // barrier
743*35238bceSAndroid Build Coastguard Worker
744*35238bceSAndroid Build Coastguard Worker buf << genBarrierSource();
745*35238bceSAndroid Build Coastguard Worker
746*35238bceSAndroid Build Coastguard Worker // read
747*35238bceSAndroid Build Coastguard Worker
748*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < m_elementsPerInvocation; ++ndx)
749*35238bceSAndroid Build Coastguard Worker {
750*35238bceSAndroid Build Coastguard Worker // check another invocation's value or our own value depending on test type
751*35238bceSAndroid Build Coastguard Worker const std::string localID = (m_syncWithGroup) ? ("(gl_LocalInvocationID.xy + uvec2(" + de::toString(ndx + 1) +
752*35238bceSAndroid Build Coastguard Worker ", " + de::toString(2 * ndx) + ")) % gl_WorkGroupSize.xy") :
753*35238bceSAndroid Build Coastguard Worker ("gl_LocalInvocationID.xy");
754*35238bceSAndroid Build Coastguard Worker
755*35238bceSAndroid Build Coastguard Worker if (m_storage == STORAGE_BUFFER && m_useAtomic)
756*35238bceSAndroid Build Coastguard Worker buf << "\tallOk = allOk && (atomicExchange(sb_store.values[getIndex(" << localID << ", " << ndx
757*35238bceSAndroid Build Coastguard Worker << ")], 123) == groupNdx);\n";
758*35238bceSAndroid Build Coastguard Worker else if (m_storage == STORAGE_BUFFER && !m_useAtomic)
759*35238bceSAndroid Build Coastguard Worker buf << "\tallOk = allOk && (sb_store.values[getIndex(" << localID << ", " << ndx << ")] == groupNdx);\n";
760*35238bceSAndroid Build Coastguard Worker else if (m_storage == STORAGE_IMAGE && m_useAtomic)
761*35238bceSAndroid Build Coastguard Worker buf << "\tallOk = allOk && (imageAtomicExchange(u_image, getCoord(" << localID << ", " << ndx
762*35238bceSAndroid Build Coastguard Worker << "), 123) == groupNdx);\n";
763*35238bceSAndroid Build Coastguard Worker else if (m_storage == STORAGE_IMAGE && !m_useAtomic)
764*35238bceSAndroid Build Coastguard Worker buf << "\tallOk = allOk && (imageLoad(u_image, getCoord(" << localID << ", " << ndx
765*35238bceSAndroid Build Coastguard Worker << ")).x == groupNdx);\n";
766*35238bceSAndroid Build Coastguard Worker else
767*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
768*35238bceSAndroid Build Coastguard Worker }
769*35238bceSAndroid Build Coastguard Worker
770*35238bceSAndroid Build Coastguard Worker return buf.str();
771*35238bceSAndroid Build Coastguard Worker }
772*35238bceSAndroid Build Coastguard Worker
773*35238bceSAndroid Build Coastguard Worker class InvocationAliasWriteCase : public InterInvocationTestCase
774*35238bceSAndroid Build Coastguard Worker {
775*35238bceSAndroid Build Coastguard Worker public:
776*35238bceSAndroid Build Coastguard Worker enum TestType
777*35238bceSAndroid Build Coastguard Worker {
778*35238bceSAndroid Build Coastguard Worker TYPE_WRITE = 0,
779*35238bceSAndroid Build Coastguard Worker TYPE_OVERWRITE,
780*35238bceSAndroid Build Coastguard Worker
781*35238bceSAndroid Build Coastguard Worker TYPE_LAST
782*35238bceSAndroid Build Coastguard Worker };
783*35238bceSAndroid Build Coastguard Worker
784*35238bceSAndroid Build Coastguard Worker InvocationAliasWriteCase(Context &context, const char *name, const char *desc, TestType type, StorageType storage,
785*35238bceSAndroid Build Coastguard Worker int flags);
786*35238bceSAndroid Build Coastguard Worker
787*35238bceSAndroid Build Coastguard Worker private:
788*35238bceSAndroid Build Coastguard Worker std::string genShaderSource(void) const;
789*35238bceSAndroid Build Coastguard Worker
790*35238bceSAndroid Build Coastguard Worker const TestType m_type;
791*35238bceSAndroid Build Coastguard Worker };
792*35238bceSAndroid Build Coastguard Worker
InvocationAliasWriteCase(Context & context,const char * name,const char * desc,TestType type,StorageType storage,int flags)793*35238bceSAndroid Build Coastguard Worker InvocationAliasWriteCase::InvocationAliasWriteCase(Context &context, const char *name, const char *desc, TestType type,
794*35238bceSAndroid Build Coastguard Worker StorageType storage, int flags)
795*35238bceSAndroid Build Coastguard Worker : InterInvocationTestCase(context, name, desc, storage, flags | FLAG_ALIASING_STORAGES)
796*35238bceSAndroid Build Coastguard Worker , m_type(type)
797*35238bceSAndroid Build Coastguard Worker {
798*35238bceSAndroid Build Coastguard Worker DE_ASSERT(type < TYPE_LAST);
799*35238bceSAndroid Build Coastguard Worker }
800*35238bceSAndroid Build Coastguard Worker
genShaderSource(void) const801*35238bceSAndroid Build Coastguard Worker std::string InvocationAliasWriteCase::genShaderSource(void) const
802*35238bceSAndroid Build Coastguard Worker {
803*35238bceSAndroid Build Coastguard Worker const bool useImageAtomics = m_useAtomic && m_storage == STORAGE_IMAGE;
804*35238bceSAndroid Build Coastguard Worker std::ostringstream buf;
805*35238bceSAndroid Build Coastguard Worker
806*35238bceSAndroid Build Coastguard Worker buf << "${GLSL_VERSION_DECL}\n"
807*35238bceSAndroid Build Coastguard Worker << ((useImageAtomics) ? ("${SHADER_IMAGE_ATOMIC_REQUIRE}\n") : ("")) << "layout (local_size_x=" << m_localWidth
808*35238bceSAndroid Build Coastguard Worker << ", local_size_y=" << m_localHeight << ") in;\n"
809*35238bceSAndroid Build Coastguard Worker << "layout(binding=0, std430) buffer Output\n"
810*35238bceSAndroid Build Coastguard Worker << "{\n"
811*35238bceSAndroid Build Coastguard Worker << " highp int values[];\n"
812*35238bceSAndroid Build Coastguard Worker << "} sb_result;\n";
813*35238bceSAndroid Build Coastguard Worker
814*35238bceSAndroid Build Coastguard Worker if (m_storage == STORAGE_BUFFER)
815*35238bceSAndroid Build Coastguard Worker buf << "layout(binding=1, std430) coherent buffer Storage0\n"
816*35238bceSAndroid Build Coastguard Worker << "{\n"
817*35238bceSAndroid Build Coastguard Worker << " highp int values[];\n"
818*35238bceSAndroid Build Coastguard Worker << "} sb_store0;\n"
819*35238bceSAndroid Build Coastguard Worker << "layout(binding=2, std430) coherent buffer Storage1\n"
820*35238bceSAndroid Build Coastguard Worker << "{\n"
821*35238bceSAndroid Build Coastguard Worker << " highp int values[];\n"
822*35238bceSAndroid Build Coastguard Worker << "} sb_store1;\n"
823*35238bceSAndroid Build Coastguard Worker << "\n"
824*35238bceSAndroid Build Coastguard Worker << "highp int getIndex (in highp uvec2 localID, in highp int element)\n"
825*35238bceSAndroid Build Coastguard Worker << "{\n"
826*35238bceSAndroid Build Coastguard Worker << " highp uint groupNdx = gl_NumWorkGroups.x * gl_WorkGroupID.y + gl_WorkGroupID.x;\n"
827*35238bceSAndroid Build Coastguard Worker << " return int((localID.y * gl_NumWorkGroups.x * gl_NumWorkGroups.y * gl_WorkGroupSize.x) + (groupNdx "
828*35238bceSAndroid Build Coastguard Worker "* gl_WorkGroupSize.x) + localID.x) * "
829*35238bceSAndroid Build Coastguard Worker << m_elementsPerInvocation << " + element;\n"
830*35238bceSAndroid Build Coastguard Worker << "}\n";
831*35238bceSAndroid Build Coastguard Worker else if (m_storage == STORAGE_IMAGE)
832*35238bceSAndroid Build Coastguard Worker buf << "layout(r32i, binding=1) coherent uniform highp iimage2D u_image0;\n"
833*35238bceSAndroid Build Coastguard Worker << "layout(r32i, binding=2) coherent uniform highp iimage2D u_image1;\n"
834*35238bceSAndroid Build Coastguard Worker << "\n"
835*35238bceSAndroid Build Coastguard Worker << "highp ivec2 getCoord (in highp uvec2 localID, in highp int element)\n"
836*35238bceSAndroid Build Coastguard Worker << "{\n"
837*35238bceSAndroid Build Coastguard Worker << " return ivec2(int(gl_WorkGroupID.x * gl_WorkGroupSize.x + localID.x), int(gl_WorkGroupID.y * "
838*35238bceSAndroid Build Coastguard Worker "gl_WorkGroupSize.y + localID.y) + element * "
839*35238bceSAndroid Build Coastguard Worker << m_workHeight << ");\n"
840*35238bceSAndroid Build Coastguard Worker << "}\n";
841*35238bceSAndroid Build Coastguard Worker else
842*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
843*35238bceSAndroid Build Coastguard Worker
844*35238bceSAndroid Build Coastguard Worker buf << "\n"
845*35238bceSAndroid Build Coastguard Worker << "void main (void)\n"
846*35238bceSAndroid Build Coastguard Worker << "{\n"
847*35238bceSAndroid Build Coastguard Worker << " int resultNdx = int(gl_GlobalInvocationID.y * gl_NumWorkGroups.x * gl_WorkGroupSize.x + "
848*35238bceSAndroid Build Coastguard Worker "gl_GlobalInvocationID.x);\n"
849*35238bceSAndroid Build Coastguard Worker << " int groupNdx = int(gl_NumWorkGroups.x * gl_WorkGroupID.y + gl_WorkGroupID.x);\n"
850*35238bceSAndroid Build Coastguard Worker << " bool allOk = true;\n"
851*35238bceSAndroid Build Coastguard Worker << "\n";
852*35238bceSAndroid Build Coastguard Worker
853*35238bceSAndroid Build Coastguard Worker if (m_type == TYPE_OVERWRITE)
854*35238bceSAndroid Build Coastguard Worker {
855*35238bceSAndroid Build Coastguard Worker // write
856*35238bceSAndroid Build Coastguard Worker
857*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < m_elementsPerInvocation; ++ndx)
858*35238bceSAndroid Build Coastguard Worker {
859*35238bceSAndroid Build Coastguard Worker if (m_storage == STORAGE_BUFFER && m_useAtomic)
860*35238bceSAndroid Build Coastguard Worker buf << "\tatomicAdd(sb_store0.values[getIndex(gl_LocalInvocationID.xy, " << ndx << ")], 456);\n";
861*35238bceSAndroid Build Coastguard Worker else if (m_storage == STORAGE_BUFFER && !m_useAtomic)
862*35238bceSAndroid Build Coastguard Worker buf << "\tsb_store0.values[getIndex(gl_LocalInvocationID.xy, " << ndx << ")] = 456;\n";
863*35238bceSAndroid Build Coastguard Worker else if (m_storage == STORAGE_IMAGE && m_useAtomic)
864*35238bceSAndroid Build Coastguard Worker buf << "\timageAtomicAdd(u_image0, getCoord(gl_LocalInvocationID.xy, " << ndx << "), 456);\n";
865*35238bceSAndroid Build Coastguard Worker else if (m_storage == STORAGE_IMAGE && !m_useAtomic)
866*35238bceSAndroid Build Coastguard Worker buf << "\timageStore(u_image0, getCoord(gl_LocalInvocationID.xy, " << ndx
867*35238bceSAndroid Build Coastguard Worker << "), ivec4(456, 0, 0, 0));\n";
868*35238bceSAndroid Build Coastguard Worker else
869*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
870*35238bceSAndroid Build Coastguard Worker }
871*35238bceSAndroid Build Coastguard Worker
872*35238bceSAndroid Build Coastguard Worker // barrier
873*35238bceSAndroid Build Coastguard Worker
874*35238bceSAndroid Build Coastguard Worker buf << genBarrierSource();
875*35238bceSAndroid Build Coastguard Worker }
876*35238bceSAndroid Build Coastguard Worker else
877*35238bceSAndroid Build Coastguard Worker DE_ASSERT(m_type == TYPE_WRITE);
878*35238bceSAndroid Build Coastguard Worker
879*35238bceSAndroid Build Coastguard Worker // write (again)
880*35238bceSAndroid Build Coastguard Worker
881*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < m_elementsPerInvocation; ++ndx)
882*35238bceSAndroid Build Coastguard Worker {
883*35238bceSAndroid Build Coastguard Worker const std::string localID = (m_syncWithGroup) ? ("(gl_LocalInvocationID.xy + uvec2(" + de::toString(ndx + 2) +
884*35238bceSAndroid Build Coastguard Worker ", " + de::toString(2 * ndx) + ")) % gl_WorkGroupSize.xy") :
885*35238bceSAndroid Build Coastguard Worker ("gl_LocalInvocationID.xy");
886*35238bceSAndroid Build Coastguard Worker
887*35238bceSAndroid Build Coastguard Worker if (m_storage == STORAGE_BUFFER && m_useAtomic)
888*35238bceSAndroid Build Coastguard Worker buf << "\tatomicExchange(sb_store1.values[getIndex(" << localID << ", " << ndx << ")], groupNdx);\n";
889*35238bceSAndroid Build Coastguard Worker else if (m_storage == STORAGE_BUFFER && !m_useAtomic)
890*35238bceSAndroid Build Coastguard Worker buf << "\tsb_store1.values[getIndex(" << localID << ", " << ndx << ")] = groupNdx;\n";
891*35238bceSAndroid Build Coastguard Worker else if (m_storage == STORAGE_IMAGE && m_useAtomic)
892*35238bceSAndroid Build Coastguard Worker buf << "\timageAtomicExchange(u_image1, getCoord(" << localID << ", " << ndx << "), groupNdx);\n";
893*35238bceSAndroid Build Coastguard Worker else if (m_storage == STORAGE_IMAGE && !m_useAtomic)
894*35238bceSAndroid Build Coastguard Worker buf << "\timageStore(u_image1, getCoord(" << localID << ", " << ndx << "), ivec4(groupNdx, 0, 0, 0));\n";
895*35238bceSAndroid Build Coastguard Worker else
896*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
897*35238bceSAndroid Build Coastguard Worker }
898*35238bceSAndroid Build Coastguard Worker
899*35238bceSAndroid Build Coastguard Worker // barrier
900*35238bceSAndroid Build Coastguard Worker
901*35238bceSAndroid Build Coastguard Worker buf << genBarrierSource();
902*35238bceSAndroid Build Coastguard Worker
903*35238bceSAndroid Build Coastguard Worker // read
904*35238bceSAndroid Build Coastguard Worker
905*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < m_elementsPerInvocation; ++ndx)
906*35238bceSAndroid Build Coastguard Worker {
907*35238bceSAndroid Build Coastguard Worker if (m_storage == STORAGE_BUFFER && m_useAtomic)
908*35238bceSAndroid Build Coastguard Worker buf << "\tallOk = allOk && (atomicExchange(sb_store0.values[getIndex(gl_LocalInvocationID.xy, " << ndx
909*35238bceSAndroid Build Coastguard Worker << ")], 123) == groupNdx);\n";
910*35238bceSAndroid Build Coastguard Worker else if (m_storage == STORAGE_BUFFER && !m_useAtomic)
911*35238bceSAndroid Build Coastguard Worker buf << "\tallOk = allOk && (sb_store0.values[getIndex(gl_LocalInvocationID.xy, " << ndx
912*35238bceSAndroid Build Coastguard Worker << ")] == groupNdx);\n";
913*35238bceSAndroid Build Coastguard Worker else if (m_storage == STORAGE_IMAGE && m_useAtomic)
914*35238bceSAndroid Build Coastguard Worker buf << "\tallOk = allOk && (imageAtomicExchange(u_image0, getCoord(gl_LocalInvocationID.xy, " << ndx
915*35238bceSAndroid Build Coastguard Worker << "), 123) == groupNdx);\n";
916*35238bceSAndroid Build Coastguard Worker else if (m_storage == STORAGE_IMAGE && !m_useAtomic)
917*35238bceSAndroid Build Coastguard Worker buf << "\tallOk = allOk && (imageLoad(u_image0, getCoord(gl_LocalInvocationID.xy, " << ndx
918*35238bceSAndroid Build Coastguard Worker << ")).x == groupNdx);\n";
919*35238bceSAndroid Build Coastguard Worker else
920*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
921*35238bceSAndroid Build Coastguard Worker }
922*35238bceSAndroid Build Coastguard Worker
923*35238bceSAndroid Build Coastguard Worker // return result
924*35238bceSAndroid Build Coastguard Worker
925*35238bceSAndroid Build Coastguard Worker buf << "\n"
926*35238bceSAndroid Build Coastguard Worker << " sb_result.values[resultNdx] = (allOk) ? (1) : (0);\n"
927*35238bceSAndroid Build Coastguard Worker << "}\n";
928*35238bceSAndroid Build Coastguard Worker
929*35238bceSAndroid Build Coastguard Worker return specializeShader(m_context, buf.str().c_str());
930*35238bceSAndroid Build Coastguard Worker }
931*35238bceSAndroid Build Coastguard Worker
932*35238bceSAndroid Build Coastguard Worker namespace op
933*35238bceSAndroid Build Coastguard Worker {
934*35238bceSAndroid Build Coastguard Worker
935*35238bceSAndroid Build Coastguard Worker struct WriteData
936*35238bceSAndroid Build Coastguard Worker {
937*35238bceSAndroid Build Coastguard Worker int targetHandle;
938*35238bceSAndroid Build Coastguard Worker int seed;
939*35238bceSAndroid Build Coastguard Worker
Generatedeqp::gles31::Functional::__anon966269800111::op::WriteData940*35238bceSAndroid Build Coastguard Worker static WriteData Generate(int targetHandle, int seed)
941*35238bceSAndroid Build Coastguard Worker {
942*35238bceSAndroid Build Coastguard Worker WriteData retVal;
943*35238bceSAndroid Build Coastguard Worker
944*35238bceSAndroid Build Coastguard Worker retVal.targetHandle = targetHandle;
945*35238bceSAndroid Build Coastguard Worker retVal.seed = seed;
946*35238bceSAndroid Build Coastguard Worker
947*35238bceSAndroid Build Coastguard Worker return retVal;
948*35238bceSAndroid Build Coastguard Worker }
949*35238bceSAndroid Build Coastguard Worker };
950*35238bceSAndroid Build Coastguard Worker
951*35238bceSAndroid Build Coastguard Worker struct ReadData
952*35238bceSAndroid Build Coastguard Worker {
953*35238bceSAndroid Build Coastguard Worker int targetHandle;
954*35238bceSAndroid Build Coastguard Worker int seed;
955*35238bceSAndroid Build Coastguard Worker
Generatedeqp::gles31::Functional::__anon966269800111::op::ReadData956*35238bceSAndroid Build Coastguard Worker static ReadData Generate(int targetHandle, int seed)
957*35238bceSAndroid Build Coastguard Worker {
958*35238bceSAndroid Build Coastguard Worker ReadData retVal;
959*35238bceSAndroid Build Coastguard Worker
960*35238bceSAndroid Build Coastguard Worker retVal.targetHandle = targetHandle;
961*35238bceSAndroid Build Coastguard Worker retVal.seed = seed;
962*35238bceSAndroid Build Coastguard Worker
963*35238bceSAndroid Build Coastguard Worker return retVal;
964*35238bceSAndroid Build Coastguard Worker }
965*35238bceSAndroid Build Coastguard Worker };
966*35238bceSAndroid Build Coastguard Worker
967*35238bceSAndroid Build Coastguard Worker struct Barrier
968*35238bceSAndroid Build Coastguard Worker {
969*35238bceSAndroid Build Coastguard Worker };
970*35238bceSAndroid Build Coastguard Worker
971*35238bceSAndroid Build Coastguard Worker struct WriteDataInterleaved
972*35238bceSAndroid Build Coastguard Worker {
973*35238bceSAndroid Build Coastguard Worker int targetHandle;
974*35238bceSAndroid Build Coastguard Worker int seed;
975*35238bceSAndroid Build Coastguard Worker bool evenOdd;
976*35238bceSAndroid Build Coastguard Worker
Generatedeqp::gles31::Functional::__anon966269800111::op::WriteDataInterleaved977*35238bceSAndroid Build Coastguard Worker static WriteDataInterleaved Generate(int targetHandle, int seed, bool evenOdd)
978*35238bceSAndroid Build Coastguard Worker {
979*35238bceSAndroid Build Coastguard Worker WriteDataInterleaved retVal;
980*35238bceSAndroid Build Coastguard Worker
981*35238bceSAndroid Build Coastguard Worker retVal.targetHandle = targetHandle;
982*35238bceSAndroid Build Coastguard Worker retVal.seed = seed;
983*35238bceSAndroid Build Coastguard Worker retVal.evenOdd = evenOdd;
984*35238bceSAndroid Build Coastguard Worker
985*35238bceSAndroid Build Coastguard Worker return retVal;
986*35238bceSAndroid Build Coastguard Worker }
987*35238bceSAndroid Build Coastguard Worker };
988*35238bceSAndroid Build Coastguard Worker
989*35238bceSAndroid Build Coastguard Worker struct ReadDataInterleaved
990*35238bceSAndroid Build Coastguard Worker {
991*35238bceSAndroid Build Coastguard Worker int targetHandle;
992*35238bceSAndroid Build Coastguard Worker int seed0;
993*35238bceSAndroid Build Coastguard Worker int seed1;
994*35238bceSAndroid Build Coastguard Worker
Generatedeqp::gles31::Functional::__anon966269800111::op::ReadDataInterleaved995*35238bceSAndroid Build Coastguard Worker static ReadDataInterleaved Generate(int targetHandle, int seed0, int seed1)
996*35238bceSAndroid Build Coastguard Worker {
997*35238bceSAndroid Build Coastguard Worker ReadDataInterleaved retVal;
998*35238bceSAndroid Build Coastguard Worker
999*35238bceSAndroid Build Coastguard Worker retVal.targetHandle = targetHandle;
1000*35238bceSAndroid Build Coastguard Worker retVal.seed0 = seed0;
1001*35238bceSAndroid Build Coastguard Worker retVal.seed1 = seed1;
1002*35238bceSAndroid Build Coastguard Worker
1003*35238bceSAndroid Build Coastguard Worker return retVal;
1004*35238bceSAndroid Build Coastguard Worker }
1005*35238bceSAndroid Build Coastguard Worker };
1006*35238bceSAndroid Build Coastguard Worker
1007*35238bceSAndroid Build Coastguard Worker struct ReadMultipleData
1008*35238bceSAndroid Build Coastguard Worker {
1009*35238bceSAndroid Build Coastguard Worker int targetHandle0;
1010*35238bceSAndroid Build Coastguard Worker int seed0;
1011*35238bceSAndroid Build Coastguard Worker int targetHandle1;
1012*35238bceSAndroid Build Coastguard Worker int seed1;
1013*35238bceSAndroid Build Coastguard Worker
Generatedeqp::gles31::Functional::__anon966269800111::op::ReadMultipleData1014*35238bceSAndroid Build Coastguard Worker static ReadMultipleData Generate(int targetHandle0, int seed0, int targetHandle1, int seed1)
1015*35238bceSAndroid Build Coastguard Worker {
1016*35238bceSAndroid Build Coastguard Worker ReadMultipleData retVal;
1017*35238bceSAndroid Build Coastguard Worker
1018*35238bceSAndroid Build Coastguard Worker retVal.targetHandle0 = targetHandle0;
1019*35238bceSAndroid Build Coastguard Worker retVal.seed0 = seed0;
1020*35238bceSAndroid Build Coastguard Worker retVal.targetHandle1 = targetHandle1;
1021*35238bceSAndroid Build Coastguard Worker retVal.seed1 = seed1;
1022*35238bceSAndroid Build Coastguard Worker
1023*35238bceSAndroid Build Coastguard Worker return retVal;
1024*35238bceSAndroid Build Coastguard Worker }
1025*35238bceSAndroid Build Coastguard Worker };
1026*35238bceSAndroid Build Coastguard Worker
1027*35238bceSAndroid Build Coastguard Worker struct ReadZeroData
1028*35238bceSAndroid Build Coastguard Worker {
1029*35238bceSAndroid Build Coastguard Worker int targetHandle;
1030*35238bceSAndroid Build Coastguard Worker
Generatedeqp::gles31::Functional::__anon966269800111::op::ReadZeroData1031*35238bceSAndroid Build Coastguard Worker static ReadZeroData Generate(int targetHandle)
1032*35238bceSAndroid Build Coastguard Worker {
1033*35238bceSAndroid Build Coastguard Worker ReadZeroData retVal;
1034*35238bceSAndroid Build Coastguard Worker
1035*35238bceSAndroid Build Coastguard Worker retVal.targetHandle = targetHandle;
1036*35238bceSAndroid Build Coastguard Worker
1037*35238bceSAndroid Build Coastguard Worker return retVal;
1038*35238bceSAndroid Build Coastguard Worker }
1039*35238bceSAndroid Build Coastguard Worker };
1040*35238bceSAndroid Build Coastguard Worker
1041*35238bceSAndroid Build Coastguard Worker } // namespace op
1042*35238bceSAndroid Build Coastguard Worker
1043*35238bceSAndroid Build Coastguard Worker class InterCallTestCase;
1044*35238bceSAndroid Build Coastguard Worker
1045*35238bceSAndroid Build Coastguard Worker class InterCallOperations
1046*35238bceSAndroid Build Coastguard Worker {
1047*35238bceSAndroid Build Coastguard Worker public:
1048*35238bceSAndroid Build Coastguard Worker InterCallOperations &operator<<(const op::WriteData &);
1049*35238bceSAndroid Build Coastguard Worker InterCallOperations &operator<<(const op::ReadData &);
1050*35238bceSAndroid Build Coastguard Worker InterCallOperations &operator<<(const op::Barrier &);
1051*35238bceSAndroid Build Coastguard Worker InterCallOperations &operator<<(const op::ReadMultipleData &);
1052*35238bceSAndroid Build Coastguard Worker InterCallOperations &operator<<(const op::WriteDataInterleaved &);
1053*35238bceSAndroid Build Coastguard Worker InterCallOperations &operator<<(const op::ReadDataInterleaved &);
1054*35238bceSAndroid Build Coastguard Worker InterCallOperations &operator<<(const op::ReadZeroData &);
1055*35238bceSAndroid Build Coastguard Worker
1056*35238bceSAndroid Build Coastguard Worker private:
1057*35238bceSAndroid Build Coastguard Worker struct Command
1058*35238bceSAndroid Build Coastguard Worker {
1059*35238bceSAndroid Build Coastguard Worker enum CommandType
1060*35238bceSAndroid Build Coastguard Worker {
1061*35238bceSAndroid Build Coastguard Worker TYPE_WRITE = 0,
1062*35238bceSAndroid Build Coastguard Worker TYPE_READ,
1063*35238bceSAndroid Build Coastguard Worker TYPE_BARRIER,
1064*35238bceSAndroid Build Coastguard Worker TYPE_READ_MULTIPLE,
1065*35238bceSAndroid Build Coastguard Worker TYPE_WRITE_INTERLEAVE,
1066*35238bceSAndroid Build Coastguard Worker TYPE_READ_INTERLEAVE,
1067*35238bceSAndroid Build Coastguard Worker TYPE_READ_ZERO,
1068*35238bceSAndroid Build Coastguard Worker
1069*35238bceSAndroid Build Coastguard Worker TYPE_LAST
1070*35238bceSAndroid Build Coastguard Worker };
1071*35238bceSAndroid Build Coastguard Worker
1072*35238bceSAndroid Build Coastguard Worker CommandType type;
1073*35238bceSAndroid Build Coastguard Worker
1074*35238bceSAndroid Build Coastguard Worker union CommandUnion
1075*35238bceSAndroid Build Coastguard Worker {
1076*35238bceSAndroid Build Coastguard Worker op::WriteData write;
1077*35238bceSAndroid Build Coastguard Worker op::ReadData read;
1078*35238bceSAndroid Build Coastguard Worker op::Barrier barrier;
1079*35238bceSAndroid Build Coastguard Worker op::ReadMultipleData readMulti;
1080*35238bceSAndroid Build Coastguard Worker op::WriteDataInterleaved writeInterleave;
1081*35238bceSAndroid Build Coastguard Worker op::ReadDataInterleaved readInterleave;
1082*35238bceSAndroid Build Coastguard Worker op::ReadZeroData readZero;
1083*35238bceSAndroid Build Coastguard Worker } u_cmd;
1084*35238bceSAndroid Build Coastguard Worker };
1085*35238bceSAndroid Build Coastguard Worker
1086*35238bceSAndroid Build Coastguard Worker friend class InterCallTestCase;
1087*35238bceSAndroid Build Coastguard Worker
1088*35238bceSAndroid Build Coastguard Worker std::vector<Command> m_cmds;
1089*35238bceSAndroid Build Coastguard Worker };
1090*35238bceSAndroid Build Coastguard Worker
operator <<(const op::WriteData & cmd)1091*35238bceSAndroid Build Coastguard Worker InterCallOperations &InterCallOperations::operator<<(const op::WriteData &cmd)
1092*35238bceSAndroid Build Coastguard Worker {
1093*35238bceSAndroid Build Coastguard Worker m_cmds.push_back(Command());
1094*35238bceSAndroid Build Coastguard Worker m_cmds.back().type = Command::TYPE_WRITE;
1095*35238bceSAndroid Build Coastguard Worker m_cmds.back().u_cmd.write = cmd;
1096*35238bceSAndroid Build Coastguard Worker
1097*35238bceSAndroid Build Coastguard Worker return *this;
1098*35238bceSAndroid Build Coastguard Worker }
1099*35238bceSAndroid Build Coastguard Worker
operator <<(const op::ReadData & cmd)1100*35238bceSAndroid Build Coastguard Worker InterCallOperations &InterCallOperations::operator<<(const op::ReadData &cmd)
1101*35238bceSAndroid Build Coastguard Worker {
1102*35238bceSAndroid Build Coastguard Worker m_cmds.push_back(Command());
1103*35238bceSAndroid Build Coastguard Worker m_cmds.back().type = Command::TYPE_READ;
1104*35238bceSAndroid Build Coastguard Worker m_cmds.back().u_cmd.read = cmd;
1105*35238bceSAndroid Build Coastguard Worker
1106*35238bceSAndroid Build Coastguard Worker return *this;
1107*35238bceSAndroid Build Coastguard Worker }
1108*35238bceSAndroid Build Coastguard Worker
operator <<(const op::Barrier & cmd)1109*35238bceSAndroid Build Coastguard Worker InterCallOperations &InterCallOperations::operator<<(const op::Barrier &cmd)
1110*35238bceSAndroid Build Coastguard Worker {
1111*35238bceSAndroid Build Coastguard Worker m_cmds.push_back(Command());
1112*35238bceSAndroid Build Coastguard Worker m_cmds.back().type = Command::TYPE_BARRIER;
1113*35238bceSAndroid Build Coastguard Worker m_cmds.back().u_cmd.barrier = cmd;
1114*35238bceSAndroid Build Coastguard Worker
1115*35238bceSAndroid Build Coastguard Worker return *this;
1116*35238bceSAndroid Build Coastguard Worker }
1117*35238bceSAndroid Build Coastguard Worker
operator <<(const op::ReadMultipleData & cmd)1118*35238bceSAndroid Build Coastguard Worker InterCallOperations &InterCallOperations::operator<<(const op::ReadMultipleData &cmd)
1119*35238bceSAndroid Build Coastguard Worker {
1120*35238bceSAndroid Build Coastguard Worker m_cmds.push_back(Command());
1121*35238bceSAndroid Build Coastguard Worker m_cmds.back().type = Command::TYPE_READ_MULTIPLE;
1122*35238bceSAndroid Build Coastguard Worker m_cmds.back().u_cmd.readMulti = cmd;
1123*35238bceSAndroid Build Coastguard Worker
1124*35238bceSAndroid Build Coastguard Worker return *this;
1125*35238bceSAndroid Build Coastguard Worker }
1126*35238bceSAndroid Build Coastguard Worker
operator <<(const op::WriteDataInterleaved & cmd)1127*35238bceSAndroid Build Coastguard Worker InterCallOperations &InterCallOperations::operator<<(const op::WriteDataInterleaved &cmd)
1128*35238bceSAndroid Build Coastguard Worker {
1129*35238bceSAndroid Build Coastguard Worker m_cmds.push_back(Command());
1130*35238bceSAndroid Build Coastguard Worker m_cmds.back().type = Command::TYPE_WRITE_INTERLEAVE;
1131*35238bceSAndroid Build Coastguard Worker m_cmds.back().u_cmd.writeInterleave = cmd;
1132*35238bceSAndroid Build Coastguard Worker
1133*35238bceSAndroid Build Coastguard Worker return *this;
1134*35238bceSAndroid Build Coastguard Worker }
1135*35238bceSAndroid Build Coastguard Worker
operator <<(const op::ReadDataInterleaved & cmd)1136*35238bceSAndroid Build Coastguard Worker InterCallOperations &InterCallOperations::operator<<(const op::ReadDataInterleaved &cmd)
1137*35238bceSAndroid Build Coastguard Worker {
1138*35238bceSAndroid Build Coastguard Worker m_cmds.push_back(Command());
1139*35238bceSAndroid Build Coastguard Worker m_cmds.back().type = Command::TYPE_READ_INTERLEAVE;
1140*35238bceSAndroid Build Coastguard Worker m_cmds.back().u_cmd.readInterleave = cmd;
1141*35238bceSAndroid Build Coastguard Worker
1142*35238bceSAndroid Build Coastguard Worker return *this;
1143*35238bceSAndroid Build Coastguard Worker }
1144*35238bceSAndroid Build Coastguard Worker
operator <<(const op::ReadZeroData & cmd)1145*35238bceSAndroid Build Coastguard Worker InterCallOperations &InterCallOperations::operator<<(const op::ReadZeroData &cmd)
1146*35238bceSAndroid Build Coastguard Worker {
1147*35238bceSAndroid Build Coastguard Worker m_cmds.push_back(Command());
1148*35238bceSAndroid Build Coastguard Worker m_cmds.back().type = Command::TYPE_READ_ZERO;
1149*35238bceSAndroid Build Coastguard Worker m_cmds.back().u_cmd.readZero = cmd;
1150*35238bceSAndroid Build Coastguard Worker
1151*35238bceSAndroid Build Coastguard Worker return *this;
1152*35238bceSAndroid Build Coastguard Worker }
1153*35238bceSAndroid Build Coastguard Worker
1154*35238bceSAndroid Build Coastguard Worker class InterCallTestCase : public TestCase
1155*35238bceSAndroid Build Coastguard Worker {
1156*35238bceSAndroid Build Coastguard Worker public:
1157*35238bceSAndroid Build Coastguard Worker enum StorageType
1158*35238bceSAndroid Build Coastguard Worker {
1159*35238bceSAndroid Build Coastguard Worker STORAGE_BUFFER = 0,
1160*35238bceSAndroid Build Coastguard Worker STORAGE_IMAGE,
1161*35238bceSAndroid Build Coastguard Worker
1162*35238bceSAndroid Build Coastguard Worker STORAGE_LAST
1163*35238bceSAndroid Build Coastguard Worker };
1164*35238bceSAndroid Build Coastguard Worker enum Flags
1165*35238bceSAndroid Build Coastguard Worker {
1166*35238bceSAndroid Build Coastguard Worker FLAG_USE_ATOMIC = 1,
1167*35238bceSAndroid Build Coastguard Worker FLAG_USE_INT = 2,
1168*35238bceSAndroid Build Coastguard Worker };
1169*35238bceSAndroid Build Coastguard Worker InterCallTestCase(Context &context, const char *name, const char *desc, StorageType storage, int flags,
1170*35238bceSAndroid Build Coastguard Worker const InterCallOperations &ops);
1171*35238bceSAndroid Build Coastguard Worker ~InterCallTestCase(void);
1172*35238bceSAndroid Build Coastguard Worker
1173*35238bceSAndroid Build Coastguard Worker private:
1174*35238bceSAndroid Build Coastguard Worker void init(void);
1175*35238bceSAndroid Build Coastguard Worker void deinit(void);
1176*35238bceSAndroid Build Coastguard Worker IterateResult iterate(void);
1177*35238bceSAndroid Build Coastguard Worker bool verifyResults(void);
1178*35238bceSAndroid Build Coastguard Worker
1179*35238bceSAndroid Build Coastguard Worker void runCommand(const op::WriteData &cmd, int stepNdx, int &programFriendlyName);
1180*35238bceSAndroid Build Coastguard Worker void runCommand(const op::ReadData &cmd, int stepNdx, int &programFriendlyName, int &resultStorageFriendlyName);
1181*35238bceSAndroid Build Coastguard Worker void runCommand(const op::Barrier &);
1182*35238bceSAndroid Build Coastguard Worker void runCommand(const op::ReadMultipleData &cmd, int stepNdx, int &programFriendlyName,
1183*35238bceSAndroid Build Coastguard Worker int &resultStorageFriendlyName);
1184*35238bceSAndroid Build Coastguard Worker void runCommand(const op::WriteDataInterleaved &cmd, int stepNdx, int &programFriendlyName);
1185*35238bceSAndroid Build Coastguard Worker void runCommand(const op::ReadDataInterleaved &cmd, int stepNdx, int &programFriendlyName,
1186*35238bceSAndroid Build Coastguard Worker int &resultStorageFriendlyName);
1187*35238bceSAndroid Build Coastguard Worker void runCommand(const op::ReadZeroData &cmd, int stepNdx, int &programFriendlyName, int &resultStorageFriendlyName);
1188*35238bceSAndroid Build Coastguard Worker void runSingleRead(int targetHandle, int stepNdx, int &programFriendlyName, int &resultStorageFriendlyName);
1189*35238bceSAndroid Build Coastguard Worker
1190*35238bceSAndroid Build Coastguard Worker glw::GLuint genStorage(int friendlyName);
1191*35238bceSAndroid Build Coastguard Worker glw::GLuint genResultStorage(void);
1192*35238bceSAndroid Build Coastguard Worker glu::ShaderProgram *genWriteProgram(int seed);
1193*35238bceSAndroid Build Coastguard Worker glu::ShaderProgram *genReadProgram(int seed);
1194*35238bceSAndroid Build Coastguard Worker glu::ShaderProgram *genReadMultipleProgram(int seed0, int seed1);
1195*35238bceSAndroid Build Coastguard Worker glu::ShaderProgram *genWriteInterleavedProgram(int seed, bool evenOdd);
1196*35238bceSAndroid Build Coastguard Worker glu::ShaderProgram *genReadInterleavedProgram(int seed0, int seed1);
1197*35238bceSAndroid Build Coastguard Worker glu::ShaderProgram *genReadZeroProgram(void);
1198*35238bceSAndroid Build Coastguard Worker
1199*35238bceSAndroid Build Coastguard Worker const StorageType m_storage;
1200*35238bceSAndroid Build Coastguard Worker const int m_invocationGridSize; // !< width and height of the two dimensional work dispatch
1201*35238bceSAndroid Build Coastguard Worker const int m_perInvocationSize; // !< number of elements accessed in single invocation
1202*35238bceSAndroid Build Coastguard Worker const std::vector<InterCallOperations::Command> m_cmds;
1203*35238bceSAndroid Build Coastguard Worker const bool m_useAtomic;
1204*35238bceSAndroid Build Coastguard Worker const bool m_formatInteger;
1205*35238bceSAndroid Build Coastguard Worker
1206*35238bceSAndroid Build Coastguard Worker std::vector<glu::ShaderProgram *> m_operationPrograms;
1207*35238bceSAndroid Build Coastguard Worker std::vector<glw::GLuint> m_operationResultStorages;
1208*35238bceSAndroid Build Coastguard Worker std::map<int, glw::GLuint> m_storageIDs;
1209*35238bceSAndroid Build Coastguard Worker };
1210*35238bceSAndroid Build Coastguard Worker
InterCallTestCase(Context & context,const char * name,const char * desc,StorageType storage,int flags,const InterCallOperations & ops)1211*35238bceSAndroid Build Coastguard Worker InterCallTestCase::InterCallTestCase(Context &context, const char *name, const char *desc, StorageType storage,
1212*35238bceSAndroid Build Coastguard Worker int flags, const InterCallOperations &ops)
1213*35238bceSAndroid Build Coastguard Worker : TestCase(context, name, desc)
1214*35238bceSAndroid Build Coastguard Worker , m_storage(storage)
1215*35238bceSAndroid Build Coastguard Worker , m_invocationGridSize(512)
1216*35238bceSAndroid Build Coastguard Worker , m_perInvocationSize(2)
1217*35238bceSAndroid Build Coastguard Worker , m_cmds(ops.m_cmds)
1218*35238bceSAndroid Build Coastguard Worker , m_useAtomic((flags & FLAG_USE_ATOMIC) != 0)
1219*35238bceSAndroid Build Coastguard Worker , m_formatInteger((flags & FLAG_USE_INT) != 0)
1220*35238bceSAndroid Build Coastguard Worker {
1221*35238bceSAndroid Build Coastguard Worker }
1222*35238bceSAndroid Build Coastguard Worker
~InterCallTestCase(void)1223*35238bceSAndroid Build Coastguard Worker InterCallTestCase::~InterCallTestCase(void)
1224*35238bceSAndroid Build Coastguard Worker {
1225*35238bceSAndroid Build Coastguard Worker deinit();
1226*35238bceSAndroid Build Coastguard Worker }
1227*35238bceSAndroid Build Coastguard Worker
init(void)1228*35238bceSAndroid Build Coastguard Worker void InterCallTestCase::init(void)
1229*35238bceSAndroid Build Coastguard Worker {
1230*35238bceSAndroid Build Coastguard Worker int programFriendlyName = 0;
1231*35238bceSAndroid Build Coastguard Worker
1232*35238bceSAndroid Build Coastguard Worker // requirements
1233*35238bceSAndroid Build Coastguard Worker
1234*35238bceSAndroid Build Coastguard Worker if (m_useAtomic && m_storage == STORAGE_IMAGE && !checkSupport(m_context))
1235*35238bceSAndroid Build Coastguard Worker throw tcu::NotSupportedError("Test requires GL_OES_shader_image_atomic extension");
1236*35238bceSAndroid Build Coastguard Worker
1237*35238bceSAndroid Build Coastguard Worker // generate resources and validate command list
1238*35238bceSAndroid Build Coastguard Worker
1239*35238bceSAndroid Build Coastguard Worker m_operationPrograms.resize(m_cmds.size(), DE_NULL);
1240*35238bceSAndroid Build Coastguard Worker m_operationResultStorages.resize(m_cmds.size(), 0);
1241*35238bceSAndroid Build Coastguard Worker
1242*35238bceSAndroid Build Coastguard Worker for (int step = 0; step < (int)m_cmds.size(); ++step)
1243*35238bceSAndroid Build Coastguard Worker {
1244*35238bceSAndroid Build Coastguard Worker switch (m_cmds[step].type)
1245*35238bceSAndroid Build Coastguard Worker {
1246*35238bceSAndroid Build Coastguard Worker case InterCallOperations::Command::TYPE_WRITE:
1247*35238bceSAndroid Build Coastguard Worker {
1248*35238bceSAndroid Build Coastguard Worker const op::WriteData &cmd = m_cmds[step].u_cmd.write;
1249*35238bceSAndroid Build Coastguard Worker
1250*35238bceSAndroid Build Coastguard Worker // new storage handle?
1251*35238bceSAndroid Build Coastguard Worker if (m_storageIDs.find(cmd.targetHandle) == m_storageIDs.end())
1252*35238bceSAndroid Build Coastguard Worker m_storageIDs[cmd.targetHandle] = genStorage(cmd.targetHandle);
1253*35238bceSAndroid Build Coastguard Worker
1254*35238bceSAndroid Build Coastguard Worker // program
1255*35238bceSAndroid Build Coastguard Worker {
1256*35238bceSAndroid Build Coastguard Worker glu::ShaderProgram *program = genWriteProgram(cmd.seed);
1257*35238bceSAndroid Build Coastguard Worker
1258*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Program #" << ++programFriendlyName
1259*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
1260*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << *program;
1261*35238bceSAndroid Build Coastguard Worker
1262*35238bceSAndroid Build Coastguard Worker if (!program->isOk())
1263*35238bceSAndroid Build Coastguard Worker throw tcu::TestError("could not build program");
1264*35238bceSAndroid Build Coastguard Worker
1265*35238bceSAndroid Build Coastguard Worker m_operationPrograms[step] = program;
1266*35238bceSAndroid Build Coastguard Worker }
1267*35238bceSAndroid Build Coastguard Worker break;
1268*35238bceSAndroid Build Coastguard Worker }
1269*35238bceSAndroid Build Coastguard Worker
1270*35238bceSAndroid Build Coastguard Worker case InterCallOperations::Command::TYPE_READ:
1271*35238bceSAndroid Build Coastguard Worker {
1272*35238bceSAndroid Build Coastguard Worker const op::ReadData &cmd = m_cmds[step].u_cmd.read;
1273*35238bceSAndroid Build Coastguard Worker DE_ASSERT(m_storageIDs.find(cmd.targetHandle) != m_storageIDs.end());
1274*35238bceSAndroid Build Coastguard Worker
1275*35238bceSAndroid Build Coastguard Worker // program and result storage
1276*35238bceSAndroid Build Coastguard Worker {
1277*35238bceSAndroid Build Coastguard Worker glu::ShaderProgram *program = genReadProgram(cmd.seed);
1278*35238bceSAndroid Build Coastguard Worker
1279*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Program #" << ++programFriendlyName
1280*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
1281*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << *program;
1282*35238bceSAndroid Build Coastguard Worker
1283*35238bceSAndroid Build Coastguard Worker if (!program->isOk())
1284*35238bceSAndroid Build Coastguard Worker throw tcu::TestError("could not build program");
1285*35238bceSAndroid Build Coastguard Worker
1286*35238bceSAndroid Build Coastguard Worker m_operationPrograms[step] = program;
1287*35238bceSAndroid Build Coastguard Worker m_operationResultStorages[step] = genResultStorage();
1288*35238bceSAndroid Build Coastguard Worker }
1289*35238bceSAndroid Build Coastguard Worker break;
1290*35238bceSAndroid Build Coastguard Worker }
1291*35238bceSAndroid Build Coastguard Worker
1292*35238bceSAndroid Build Coastguard Worker case InterCallOperations::Command::TYPE_BARRIER:
1293*35238bceSAndroid Build Coastguard Worker {
1294*35238bceSAndroid Build Coastguard Worker break;
1295*35238bceSAndroid Build Coastguard Worker }
1296*35238bceSAndroid Build Coastguard Worker
1297*35238bceSAndroid Build Coastguard Worker case InterCallOperations::Command::TYPE_READ_MULTIPLE:
1298*35238bceSAndroid Build Coastguard Worker {
1299*35238bceSAndroid Build Coastguard Worker const op::ReadMultipleData &cmd = m_cmds[step].u_cmd.readMulti;
1300*35238bceSAndroid Build Coastguard Worker DE_ASSERT(m_storageIDs.find(cmd.targetHandle0) != m_storageIDs.end());
1301*35238bceSAndroid Build Coastguard Worker DE_ASSERT(m_storageIDs.find(cmd.targetHandle1) != m_storageIDs.end());
1302*35238bceSAndroid Build Coastguard Worker
1303*35238bceSAndroid Build Coastguard Worker // program
1304*35238bceSAndroid Build Coastguard Worker {
1305*35238bceSAndroid Build Coastguard Worker glu::ShaderProgram *program = genReadMultipleProgram(cmd.seed0, cmd.seed1);
1306*35238bceSAndroid Build Coastguard Worker
1307*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Program #" << ++programFriendlyName
1308*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
1309*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << *program;
1310*35238bceSAndroid Build Coastguard Worker
1311*35238bceSAndroid Build Coastguard Worker if (!program->isOk())
1312*35238bceSAndroid Build Coastguard Worker throw tcu::TestError("could not build program");
1313*35238bceSAndroid Build Coastguard Worker
1314*35238bceSAndroid Build Coastguard Worker m_operationPrograms[step] = program;
1315*35238bceSAndroid Build Coastguard Worker m_operationResultStorages[step] = genResultStorage();
1316*35238bceSAndroid Build Coastguard Worker }
1317*35238bceSAndroid Build Coastguard Worker break;
1318*35238bceSAndroid Build Coastguard Worker }
1319*35238bceSAndroid Build Coastguard Worker
1320*35238bceSAndroid Build Coastguard Worker case InterCallOperations::Command::TYPE_WRITE_INTERLEAVE:
1321*35238bceSAndroid Build Coastguard Worker {
1322*35238bceSAndroid Build Coastguard Worker const op::WriteDataInterleaved &cmd = m_cmds[step].u_cmd.writeInterleave;
1323*35238bceSAndroid Build Coastguard Worker
1324*35238bceSAndroid Build Coastguard Worker // new storage handle?
1325*35238bceSAndroid Build Coastguard Worker if (m_storageIDs.find(cmd.targetHandle) == m_storageIDs.end())
1326*35238bceSAndroid Build Coastguard Worker m_storageIDs[cmd.targetHandle] = genStorage(cmd.targetHandle);
1327*35238bceSAndroid Build Coastguard Worker
1328*35238bceSAndroid Build Coastguard Worker // program
1329*35238bceSAndroid Build Coastguard Worker {
1330*35238bceSAndroid Build Coastguard Worker glu::ShaderProgram *program = genWriteInterleavedProgram(cmd.seed, cmd.evenOdd);
1331*35238bceSAndroid Build Coastguard Worker
1332*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Program #" << ++programFriendlyName
1333*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
1334*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << *program;
1335*35238bceSAndroid Build Coastguard Worker
1336*35238bceSAndroid Build Coastguard Worker if (!program->isOk())
1337*35238bceSAndroid Build Coastguard Worker throw tcu::TestError("could not build program");
1338*35238bceSAndroid Build Coastguard Worker
1339*35238bceSAndroid Build Coastguard Worker m_operationPrograms[step] = program;
1340*35238bceSAndroid Build Coastguard Worker }
1341*35238bceSAndroid Build Coastguard Worker break;
1342*35238bceSAndroid Build Coastguard Worker }
1343*35238bceSAndroid Build Coastguard Worker
1344*35238bceSAndroid Build Coastguard Worker case InterCallOperations::Command::TYPE_READ_INTERLEAVE:
1345*35238bceSAndroid Build Coastguard Worker {
1346*35238bceSAndroid Build Coastguard Worker const op::ReadDataInterleaved &cmd = m_cmds[step].u_cmd.readInterleave;
1347*35238bceSAndroid Build Coastguard Worker DE_ASSERT(m_storageIDs.find(cmd.targetHandle) != m_storageIDs.end());
1348*35238bceSAndroid Build Coastguard Worker
1349*35238bceSAndroid Build Coastguard Worker // program
1350*35238bceSAndroid Build Coastguard Worker {
1351*35238bceSAndroid Build Coastguard Worker glu::ShaderProgram *program = genReadInterleavedProgram(cmd.seed0, cmd.seed1);
1352*35238bceSAndroid Build Coastguard Worker
1353*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Program #" << ++programFriendlyName
1354*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
1355*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << *program;
1356*35238bceSAndroid Build Coastguard Worker
1357*35238bceSAndroid Build Coastguard Worker if (!program->isOk())
1358*35238bceSAndroid Build Coastguard Worker throw tcu::TestError("could not build program");
1359*35238bceSAndroid Build Coastguard Worker
1360*35238bceSAndroid Build Coastguard Worker m_operationPrograms[step] = program;
1361*35238bceSAndroid Build Coastguard Worker m_operationResultStorages[step] = genResultStorage();
1362*35238bceSAndroid Build Coastguard Worker }
1363*35238bceSAndroid Build Coastguard Worker break;
1364*35238bceSAndroid Build Coastguard Worker }
1365*35238bceSAndroid Build Coastguard Worker
1366*35238bceSAndroid Build Coastguard Worker case InterCallOperations::Command::TYPE_READ_ZERO:
1367*35238bceSAndroid Build Coastguard Worker {
1368*35238bceSAndroid Build Coastguard Worker const op::ReadZeroData &cmd = m_cmds[step].u_cmd.readZero;
1369*35238bceSAndroid Build Coastguard Worker
1370*35238bceSAndroid Build Coastguard Worker // new storage handle?
1371*35238bceSAndroid Build Coastguard Worker if (m_storageIDs.find(cmd.targetHandle) == m_storageIDs.end())
1372*35238bceSAndroid Build Coastguard Worker m_storageIDs[cmd.targetHandle] = genStorage(cmd.targetHandle);
1373*35238bceSAndroid Build Coastguard Worker
1374*35238bceSAndroid Build Coastguard Worker // program
1375*35238bceSAndroid Build Coastguard Worker {
1376*35238bceSAndroid Build Coastguard Worker glu::ShaderProgram *program = genReadZeroProgram();
1377*35238bceSAndroid Build Coastguard Worker
1378*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Program #" << ++programFriendlyName
1379*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
1380*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << *program;
1381*35238bceSAndroid Build Coastguard Worker
1382*35238bceSAndroid Build Coastguard Worker if (!program->isOk())
1383*35238bceSAndroid Build Coastguard Worker throw tcu::TestError("could not build program");
1384*35238bceSAndroid Build Coastguard Worker
1385*35238bceSAndroid Build Coastguard Worker m_operationPrograms[step] = program;
1386*35238bceSAndroid Build Coastguard Worker m_operationResultStorages[step] = genResultStorage();
1387*35238bceSAndroid Build Coastguard Worker }
1388*35238bceSAndroid Build Coastguard Worker break;
1389*35238bceSAndroid Build Coastguard Worker }
1390*35238bceSAndroid Build Coastguard Worker
1391*35238bceSAndroid Build Coastguard Worker default:
1392*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
1393*35238bceSAndroid Build Coastguard Worker }
1394*35238bceSAndroid Build Coastguard Worker }
1395*35238bceSAndroid Build Coastguard Worker }
1396*35238bceSAndroid Build Coastguard Worker
deinit(void)1397*35238bceSAndroid Build Coastguard Worker void InterCallTestCase::deinit(void)
1398*35238bceSAndroid Build Coastguard Worker {
1399*35238bceSAndroid Build Coastguard Worker // programs
1400*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < (int)m_operationPrograms.size(); ++ndx)
1401*35238bceSAndroid Build Coastguard Worker delete m_operationPrograms[ndx];
1402*35238bceSAndroid Build Coastguard Worker m_operationPrograms.clear();
1403*35238bceSAndroid Build Coastguard Worker
1404*35238bceSAndroid Build Coastguard Worker // result storages
1405*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < (int)m_operationResultStorages.size(); ++ndx)
1406*35238bceSAndroid Build Coastguard Worker {
1407*35238bceSAndroid Build Coastguard Worker if (m_operationResultStorages[ndx])
1408*35238bceSAndroid Build Coastguard Worker m_context.getRenderContext().getFunctions().deleteBuffers(1, &m_operationResultStorages[ndx]);
1409*35238bceSAndroid Build Coastguard Worker }
1410*35238bceSAndroid Build Coastguard Worker m_operationResultStorages.clear();
1411*35238bceSAndroid Build Coastguard Worker
1412*35238bceSAndroid Build Coastguard Worker // storage
1413*35238bceSAndroid Build Coastguard Worker for (std::map<int, glw::GLuint>::const_iterator it = m_storageIDs.begin(); it != m_storageIDs.end(); ++it)
1414*35238bceSAndroid Build Coastguard Worker {
1415*35238bceSAndroid Build Coastguard Worker const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1416*35238bceSAndroid Build Coastguard Worker
1417*35238bceSAndroid Build Coastguard Worker if (m_storage == STORAGE_BUFFER)
1418*35238bceSAndroid Build Coastguard Worker gl.deleteBuffers(1, &it->second);
1419*35238bceSAndroid Build Coastguard Worker else if (m_storage == STORAGE_IMAGE)
1420*35238bceSAndroid Build Coastguard Worker gl.deleteTextures(1, &it->second);
1421*35238bceSAndroid Build Coastguard Worker else
1422*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
1423*35238bceSAndroid Build Coastguard Worker }
1424*35238bceSAndroid Build Coastguard Worker m_storageIDs.clear();
1425*35238bceSAndroid Build Coastguard Worker }
1426*35238bceSAndroid Build Coastguard Worker
iterate(void)1427*35238bceSAndroid Build Coastguard Worker InterCallTestCase::IterateResult InterCallTestCase::iterate(void)
1428*35238bceSAndroid Build Coastguard Worker {
1429*35238bceSAndroid Build Coastguard Worker int programFriendlyName = 0;
1430*35238bceSAndroid Build Coastguard Worker int resultStorageFriendlyName = 0;
1431*35238bceSAndroid Build Coastguard Worker
1432*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Running operations:" << tcu::TestLog::EndMessage;
1433*35238bceSAndroid Build Coastguard Worker
1434*35238bceSAndroid Build Coastguard Worker // run steps
1435*35238bceSAndroid Build Coastguard Worker
1436*35238bceSAndroid Build Coastguard Worker for (int step = 0; step < (int)m_cmds.size(); ++step)
1437*35238bceSAndroid Build Coastguard Worker {
1438*35238bceSAndroid Build Coastguard Worker switch (m_cmds[step].type)
1439*35238bceSAndroid Build Coastguard Worker {
1440*35238bceSAndroid Build Coastguard Worker case InterCallOperations::Command::TYPE_WRITE:
1441*35238bceSAndroid Build Coastguard Worker runCommand(m_cmds[step].u_cmd.write, step, programFriendlyName);
1442*35238bceSAndroid Build Coastguard Worker break;
1443*35238bceSAndroid Build Coastguard Worker case InterCallOperations::Command::TYPE_READ:
1444*35238bceSAndroid Build Coastguard Worker runCommand(m_cmds[step].u_cmd.read, step, programFriendlyName, resultStorageFriendlyName);
1445*35238bceSAndroid Build Coastguard Worker break;
1446*35238bceSAndroid Build Coastguard Worker case InterCallOperations::Command::TYPE_BARRIER:
1447*35238bceSAndroid Build Coastguard Worker runCommand(m_cmds[step].u_cmd.barrier);
1448*35238bceSAndroid Build Coastguard Worker break;
1449*35238bceSAndroid Build Coastguard Worker case InterCallOperations::Command::TYPE_READ_MULTIPLE:
1450*35238bceSAndroid Build Coastguard Worker runCommand(m_cmds[step].u_cmd.readMulti, step, programFriendlyName, resultStorageFriendlyName);
1451*35238bceSAndroid Build Coastguard Worker break;
1452*35238bceSAndroid Build Coastguard Worker case InterCallOperations::Command::TYPE_WRITE_INTERLEAVE:
1453*35238bceSAndroid Build Coastguard Worker runCommand(m_cmds[step].u_cmd.writeInterleave, step, programFriendlyName);
1454*35238bceSAndroid Build Coastguard Worker break;
1455*35238bceSAndroid Build Coastguard Worker case InterCallOperations::Command::TYPE_READ_INTERLEAVE:
1456*35238bceSAndroid Build Coastguard Worker runCommand(m_cmds[step].u_cmd.readInterleave, step, programFriendlyName, resultStorageFriendlyName);
1457*35238bceSAndroid Build Coastguard Worker break;
1458*35238bceSAndroid Build Coastguard Worker case InterCallOperations::Command::TYPE_READ_ZERO:
1459*35238bceSAndroid Build Coastguard Worker runCommand(m_cmds[step].u_cmd.readZero, step, programFriendlyName, resultStorageFriendlyName);
1460*35238bceSAndroid Build Coastguard Worker break;
1461*35238bceSAndroid Build Coastguard Worker default:
1462*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
1463*35238bceSAndroid Build Coastguard Worker }
1464*35238bceSAndroid Build Coastguard Worker }
1465*35238bceSAndroid Build Coastguard Worker
1466*35238bceSAndroid Build Coastguard Worker // read results from result buffers
1467*35238bceSAndroid Build Coastguard Worker if (verifyResults())
1468*35238bceSAndroid Build Coastguard Worker m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1469*35238bceSAndroid Build Coastguard Worker else
1470*35238bceSAndroid Build Coastguard Worker m_testCtx.setTestResult(
1471*35238bceSAndroid Build Coastguard Worker QP_TEST_RESULT_FAIL,
1472*35238bceSAndroid Build Coastguard Worker (std::string((m_storage == STORAGE_BUFFER) ? ("buffer") : ("image")) + " content verification failed")
1473*35238bceSAndroid Build Coastguard Worker .c_str());
1474*35238bceSAndroid Build Coastguard Worker
1475*35238bceSAndroid Build Coastguard Worker return STOP;
1476*35238bceSAndroid Build Coastguard Worker }
1477*35238bceSAndroid Build Coastguard Worker
verifyResults(void)1478*35238bceSAndroid Build Coastguard Worker bool InterCallTestCase::verifyResults(void)
1479*35238bceSAndroid Build Coastguard Worker {
1480*35238bceSAndroid Build Coastguard Worker int resultBufferFriendlyName = 0;
1481*35238bceSAndroid Build Coastguard Worker bool allResultsOk = true;
1482*35238bceSAndroid Build Coastguard Worker bool anyResult = false;
1483*35238bceSAndroid Build Coastguard Worker
1484*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Reading verifier program results" << tcu::TestLog::EndMessage;
1485*35238bceSAndroid Build Coastguard Worker
1486*35238bceSAndroid Build Coastguard Worker for (int step = 0; step < (int)m_cmds.size(); ++step)
1487*35238bceSAndroid Build Coastguard Worker {
1488*35238bceSAndroid Build Coastguard Worker const int errorFloodThreshold = 5;
1489*35238bceSAndroid Build Coastguard Worker int numErrorsLogged = 0;
1490*35238bceSAndroid Build Coastguard Worker
1491*35238bceSAndroid Build Coastguard Worker if (m_operationResultStorages[step])
1492*35238bceSAndroid Build Coastguard Worker {
1493*35238bceSAndroid Build Coastguard Worker const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1494*35238bceSAndroid Build Coastguard Worker const void *mapped = DE_NULL;
1495*35238bceSAndroid Build Coastguard Worker std::vector<int32_t> results(m_invocationGridSize * m_invocationGridSize);
1496*35238bceSAndroid Build Coastguard Worker bool error = false;
1497*35238bceSAndroid Build Coastguard Worker
1498*35238bceSAndroid Build Coastguard Worker anyResult = true;
1499*35238bceSAndroid Build Coastguard Worker
1500*35238bceSAndroid Build Coastguard Worker gl.bindBuffer(GL_SHADER_STORAGE_BUFFER, m_operationResultStorages[step]);
1501*35238bceSAndroid Build Coastguard Worker mapped = gl.mapBufferRange(GL_SHADER_STORAGE_BUFFER, 0,
1502*35238bceSAndroid Build Coastguard Worker m_invocationGridSize * m_invocationGridSize * sizeof(uint32_t), GL_MAP_READ_BIT);
1503*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "map buffer");
1504*35238bceSAndroid Build Coastguard Worker
1505*35238bceSAndroid Build Coastguard Worker // copy to properly aligned array
1506*35238bceSAndroid Build Coastguard Worker deMemcpy(&results[0], mapped, m_invocationGridSize * m_invocationGridSize * sizeof(uint32_t));
1507*35238bceSAndroid Build Coastguard Worker
1508*35238bceSAndroid Build Coastguard Worker if (gl.unmapBuffer(GL_SHADER_STORAGE_BUFFER) != GL_TRUE)
1509*35238bceSAndroid Build Coastguard Worker throw tcu::TestError("memory map store corrupted");
1510*35238bceSAndroid Build Coastguard Worker
1511*35238bceSAndroid Build Coastguard Worker // check the results
1512*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < (int)results.size(); ++ndx)
1513*35238bceSAndroid Build Coastguard Worker {
1514*35238bceSAndroid Build Coastguard Worker if (results[ndx] != 1)
1515*35238bceSAndroid Build Coastguard Worker {
1516*35238bceSAndroid Build Coastguard Worker error = true;
1517*35238bceSAndroid Build Coastguard Worker
1518*35238bceSAndroid Build Coastguard Worker if (numErrorsLogged == 0)
1519*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Result storage #" << ++resultBufferFriendlyName
1520*35238bceSAndroid Build Coastguard Worker << " failed, got unexpected values.\n"
1521*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
1522*35238bceSAndroid Build Coastguard Worker if (numErrorsLogged++ < errorFloodThreshold)
1523*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << " Error at index " << ndx
1524*35238bceSAndroid Build Coastguard Worker << ": expected 1, got " << results[ndx] << ".\n"
1525*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
1526*35238bceSAndroid Build Coastguard Worker else
1527*35238bceSAndroid Build Coastguard Worker {
1528*35238bceSAndroid Build Coastguard Worker // after N errors, no point continuing verification
1529*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog()
1530*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::Message << " -- too many errors, skipping verification --\n"
1531*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
1532*35238bceSAndroid Build Coastguard Worker break;
1533*35238bceSAndroid Build Coastguard Worker }
1534*35238bceSAndroid Build Coastguard Worker }
1535*35238bceSAndroid Build Coastguard Worker }
1536*35238bceSAndroid Build Coastguard Worker
1537*35238bceSAndroid Build Coastguard Worker if (error)
1538*35238bceSAndroid Build Coastguard Worker {
1539*35238bceSAndroid Build Coastguard Worker allResultsOk = false;
1540*35238bceSAndroid Build Coastguard Worker }
1541*35238bceSAndroid Build Coastguard Worker else
1542*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Result storage #" << ++resultBufferFriendlyName
1543*35238bceSAndroid Build Coastguard Worker << " ok." << tcu::TestLog::EndMessage;
1544*35238bceSAndroid Build Coastguard Worker }
1545*35238bceSAndroid Build Coastguard Worker }
1546*35238bceSAndroid Build Coastguard Worker
1547*35238bceSAndroid Build Coastguard Worker DE_ASSERT(anyResult);
1548*35238bceSAndroid Build Coastguard Worker DE_UNREF(anyResult);
1549*35238bceSAndroid Build Coastguard Worker
1550*35238bceSAndroid Build Coastguard Worker return allResultsOk;
1551*35238bceSAndroid Build Coastguard Worker }
1552*35238bceSAndroid Build Coastguard Worker
runCommand(const op::WriteData & cmd,int stepNdx,int & programFriendlyName)1553*35238bceSAndroid Build Coastguard Worker void InterCallTestCase::runCommand(const op::WriteData &cmd, int stepNdx, int &programFriendlyName)
1554*35238bceSAndroid Build Coastguard Worker {
1555*35238bceSAndroid Build Coastguard Worker const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1556*35238bceSAndroid Build Coastguard Worker
1557*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Running program #" << ++programFriendlyName << " to write "
1558*35238bceSAndroid Build Coastguard Worker << ((m_storage == STORAGE_BUFFER) ? ("buffer") : ("image")) << " #" << cmd.targetHandle << ".\n"
1559*35238bceSAndroid Build Coastguard Worker << " Dispatch size: " << m_invocationGridSize << "x" << m_invocationGridSize << "."
1560*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
1561*35238bceSAndroid Build Coastguard Worker
1562*35238bceSAndroid Build Coastguard Worker gl.useProgram(m_operationPrograms[stepNdx]->getProgram());
1563*35238bceSAndroid Build Coastguard Worker
1564*35238bceSAndroid Build Coastguard Worker // set destination
1565*35238bceSAndroid Build Coastguard Worker if (m_storage == STORAGE_BUFFER)
1566*35238bceSAndroid Build Coastguard Worker {
1567*35238bceSAndroid Build Coastguard Worker DE_ASSERT(m_storageIDs[cmd.targetHandle]);
1568*35238bceSAndroid Build Coastguard Worker
1569*35238bceSAndroid Build Coastguard Worker gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_storageIDs[cmd.targetHandle]);
1570*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "bind destination buffer");
1571*35238bceSAndroid Build Coastguard Worker }
1572*35238bceSAndroid Build Coastguard Worker else if (m_storage == STORAGE_IMAGE)
1573*35238bceSAndroid Build Coastguard Worker {
1574*35238bceSAndroid Build Coastguard Worker DE_ASSERT(m_storageIDs[cmd.targetHandle]);
1575*35238bceSAndroid Build Coastguard Worker
1576*35238bceSAndroid Build Coastguard Worker gl.bindImageTexture(0, m_storageIDs[cmd.targetHandle], 0, GL_FALSE, 0,
1577*35238bceSAndroid Build Coastguard Worker (m_useAtomic) ? (GL_READ_WRITE) : (GL_WRITE_ONLY),
1578*35238bceSAndroid Build Coastguard Worker (m_formatInteger) ? (GL_R32I) : (GL_R32F));
1579*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "bind destination image");
1580*35238bceSAndroid Build Coastguard Worker }
1581*35238bceSAndroid Build Coastguard Worker else
1582*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
1583*35238bceSAndroid Build Coastguard Worker
1584*35238bceSAndroid Build Coastguard Worker // calc
1585*35238bceSAndroid Build Coastguard Worker gl.dispatchCompute(m_invocationGridSize, m_invocationGridSize, 1);
1586*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "dispatch write");
1587*35238bceSAndroid Build Coastguard Worker }
1588*35238bceSAndroid Build Coastguard Worker
runCommand(const op::ReadData & cmd,int stepNdx,int & programFriendlyName,int & resultStorageFriendlyName)1589*35238bceSAndroid Build Coastguard Worker void InterCallTestCase::runCommand(const op::ReadData &cmd, int stepNdx, int &programFriendlyName,
1590*35238bceSAndroid Build Coastguard Worker int &resultStorageFriendlyName)
1591*35238bceSAndroid Build Coastguard Worker {
1592*35238bceSAndroid Build Coastguard Worker runSingleRead(cmd.targetHandle, stepNdx, programFriendlyName, resultStorageFriendlyName);
1593*35238bceSAndroid Build Coastguard Worker }
1594*35238bceSAndroid Build Coastguard Worker
runCommand(const op::Barrier & cmd)1595*35238bceSAndroid Build Coastguard Worker void InterCallTestCase::runCommand(const op::Barrier &cmd)
1596*35238bceSAndroid Build Coastguard Worker {
1597*35238bceSAndroid Build Coastguard Worker const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1598*35238bceSAndroid Build Coastguard Worker
1599*35238bceSAndroid Build Coastguard Worker DE_UNREF(cmd);
1600*35238bceSAndroid Build Coastguard Worker
1601*35238bceSAndroid Build Coastguard Worker if (m_storage == STORAGE_BUFFER)
1602*35238bceSAndroid Build Coastguard Worker {
1603*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Memory Barrier\n\tbits = GL_SHADER_STORAGE_BARRIER_BIT"
1604*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
1605*35238bceSAndroid Build Coastguard Worker gl.memoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
1606*35238bceSAndroid Build Coastguard Worker }
1607*35238bceSAndroid Build Coastguard Worker else if (m_storage == STORAGE_IMAGE)
1608*35238bceSAndroid Build Coastguard Worker {
1609*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Memory Barrier\n\tbits = GL_SHADER_IMAGE_ACCESS_BARRIER_BIT"
1610*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
1611*35238bceSAndroid Build Coastguard Worker gl.memoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
1612*35238bceSAndroid Build Coastguard Worker }
1613*35238bceSAndroid Build Coastguard Worker else
1614*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
1615*35238bceSAndroid Build Coastguard Worker }
1616*35238bceSAndroid Build Coastguard Worker
runCommand(const op::ReadMultipleData & cmd,int stepNdx,int & programFriendlyName,int & resultStorageFriendlyName)1617*35238bceSAndroid Build Coastguard Worker void InterCallTestCase::runCommand(const op::ReadMultipleData &cmd, int stepNdx, int &programFriendlyName,
1618*35238bceSAndroid Build Coastguard Worker int &resultStorageFriendlyName)
1619*35238bceSAndroid Build Coastguard Worker {
1620*35238bceSAndroid Build Coastguard Worker const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1621*35238bceSAndroid Build Coastguard Worker
1622*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Running program #" << ++programFriendlyName << " to verify "
1623*35238bceSAndroid Build Coastguard Worker << ((m_storage == STORAGE_BUFFER) ? ("buffers") : ("images")) << " #" << cmd.targetHandle0
1624*35238bceSAndroid Build Coastguard Worker << " and #" << cmd.targetHandle1 << ".\n"
1625*35238bceSAndroid Build Coastguard Worker << " Writing results to result storage #" << ++resultStorageFriendlyName << ".\n"
1626*35238bceSAndroid Build Coastguard Worker << " Dispatch size: " << m_invocationGridSize << "x" << m_invocationGridSize << "."
1627*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
1628*35238bceSAndroid Build Coastguard Worker
1629*35238bceSAndroid Build Coastguard Worker gl.useProgram(m_operationPrograms[stepNdx]->getProgram());
1630*35238bceSAndroid Build Coastguard Worker
1631*35238bceSAndroid Build Coastguard Worker // set sources
1632*35238bceSAndroid Build Coastguard Worker if (m_storage == STORAGE_BUFFER)
1633*35238bceSAndroid Build Coastguard Worker {
1634*35238bceSAndroid Build Coastguard Worker DE_ASSERT(m_storageIDs[cmd.targetHandle0]);
1635*35238bceSAndroid Build Coastguard Worker DE_ASSERT(m_storageIDs[cmd.targetHandle1]);
1636*35238bceSAndroid Build Coastguard Worker
1637*35238bceSAndroid Build Coastguard Worker gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_storageIDs[cmd.targetHandle0]);
1638*35238bceSAndroid Build Coastguard Worker gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, m_storageIDs[cmd.targetHandle1]);
1639*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "bind source buffers");
1640*35238bceSAndroid Build Coastguard Worker }
1641*35238bceSAndroid Build Coastguard Worker else if (m_storage == STORAGE_IMAGE)
1642*35238bceSAndroid Build Coastguard Worker {
1643*35238bceSAndroid Build Coastguard Worker DE_ASSERT(m_storageIDs[cmd.targetHandle0]);
1644*35238bceSAndroid Build Coastguard Worker DE_ASSERT(m_storageIDs[cmd.targetHandle1]);
1645*35238bceSAndroid Build Coastguard Worker
1646*35238bceSAndroid Build Coastguard Worker gl.bindImageTexture(1, m_storageIDs[cmd.targetHandle0], 0, GL_FALSE, 0,
1647*35238bceSAndroid Build Coastguard Worker (m_useAtomic) ? (GL_READ_WRITE) : (GL_READ_ONLY),
1648*35238bceSAndroid Build Coastguard Worker (m_formatInteger) ? (GL_R32I) : (GL_R32F));
1649*35238bceSAndroid Build Coastguard Worker gl.bindImageTexture(2, m_storageIDs[cmd.targetHandle1], 0, GL_FALSE, 0,
1650*35238bceSAndroid Build Coastguard Worker (m_useAtomic) ? (GL_READ_WRITE) : (GL_READ_ONLY),
1651*35238bceSAndroid Build Coastguard Worker (m_formatInteger) ? (GL_R32I) : (GL_R32F));
1652*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "bind source images");
1653*35238bceSAndroid Build Coastguard Worker }
1654*35238bceSAndroid Build Coastguard Worker else
1655*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
1656*35238bceSAndroid Build Coastguard Worker
1657*35238bceSAndroid Build Coastguard Worker // set destination
1658*35238bceSAndroid Build Coastguard Worker DE_ASSERT(m_operationResultStorages[stepNdx]);
1659*35238bceSAndroid Build Coastguard Worker gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_operationResultStorages[stepNdx]);
1660*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "bind result buffer");
1661*35238bceSAndroid Build Coastguard Worker
1662*35238bceSAndroid Build Coastguard Worker // calc
1663*35238bceSAndroid Build Coastguard Worker gl.dispatchCompute(m_invocationGridSize, m_invocationGridSize, 1);
1664*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "dispatch read multi");
1665*35238bceSAndroid Build Coastguard Worker }
1666*35238bceSAndroid Build Coastguard Worker
runCommand(const op::WriteDataInterleaved & cmd,int stepNdx,int & programFriendlyName)1667*35238bceSAndroid Build Coastguard Worker void InterCallTestCase::runCommand(const op::WriteDataInterleaved &cmd, int stepNdx, int &programFriendlyName)
1668*35238bceSAndroid Build Coastguard Worker {
1669*35238bceSAndroid Build Coastguard Worker const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1670*35238bceSAndroid Build Coastguard Worker
1671*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Running program #" << ++programFriendlyName << " to write "
1672*35238bceSAndroid Build Coastguard Worker << ((m_storage == STORAGE_BUFFER) ? ("buffer") : ("image")) << " #" << cmd.targetHandle << ".\n"
1673*35238bceSAndroid Build Coastguard Worker << " Writing to every " << ((cmd.evenOdd) ? ("even") : ("odd")) << " "
1674*35238bceSAndroid Build Coastguard Worker << ((m_storage == STORAGE_BUFFER) ? ("element") : ("column")) << ".\n"
1675*35238bceSAndroid Build Coastguard Worker << " Dispatch size: " << m_invocationGridSize / 2 << "x" << m_invocationGridSize << "."
1676*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
1677*35238bceSAndroid Build Coastguard Worker
1678*35238bceSAndroid Build Coastguard Worker gl.useProgram(m_operationPrograms[stepNdx]->getProgram());
1679*35238bceSAndroid Build Coastguard Worker
1680*35238bceSAndroid Build Coastguard Worker // set destination
1681*35238bceSAndroid Build Coastguard Worker if (m_storage == STORAGE_BUFFER)
1682*35238bceSAndroid Build Coastguard Worker {
1683*35238bceSAndroid Build Coastguard Worker DE_ASSERT(m_storageIDs[cmd.targetHandle]);
1684*35238bceSAndroid Build Coastguard Worker
1685*35238bceSAndroid Build Coastguard Worker gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_storageIDs[cmd.targetHandle]);
1686*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "bind destination buffer");
1687*35238bceSAndroid Build Coastguard Worker }
1688*35238bceSAndroid Build Coastguard Worker else if (m_storage == STORAGE_IMAGE)
1689*35238bceSAndroid Build Coastguard Worker {
1690*35238bceSAndroid Build Coastguard Worker DE_ASSERT(m_storageIDs[cmd.targetHandle]);
1691*35238bceSAndroid Build Coastguard Worker
1692*35238bceSAndroid Build Coastguard Worker gl.bindImageTexture(0, m_storageIDs[cmd.targetHandle], 0, GL_FALSE, 0,
1693*35238bceSAndroid Build Coastguard Worker (m_useAtomic) ? (GL_READ_WRITE) : (GL_WRITE_ONLY),
1694*35238bceSAndroid Build Coastguard Worker (m_formatInteger) ? (GL_R32I) : (GL_R32F));
1695*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "bind destination image");
1696*35238bceSAndroid Build Coastguard Worker }
1697*35238bceSAndroid Build Coastguard Worker else
1698*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
1699*35238bceSAndroid Build Coastguard Worker
1700*35238bceSAndroid Build Coastguard Worker // calc
1701*35238bceSAndroid Build Coastguard Worker gl.dispatchCompute(m_invocationGridSize / 2, m_invocationGridSize, 1);
1702*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "dispatch write");
1703*35238bceSAndroid Build Coastguard Worker }
1704*35238bceSAndroid Build Coastguard Worker
runCommand(const op::ReadDataInterleaved & cmd,int stepNdx,int & programFriendlyName,int & resultStorageFriendlyName)1705*35238bceSAndroid Build Coastguard Worker void InterCallTestCase::runCommand(const op::ReadDataInterleaved &cmd, int stepNdx, int &programFriendlyName,
1706*35238bceSAndroid Build Coastguard Worker int &resultStorageFriendlyName)
1707*35238bceSAndroid Build Coastguard Worker {
1708*35238bceSAndroid Build Coastguard Worker runSingleRead(cmd.targetHandle, stepNdx, programFriendlyName, resultStorageFriendlyName);
1709*35238bceSAndroid Build Coastguard Worker }
1710*35238bceSAndroid Build Coastguard Worker
runCommand(const op::ReadZeroData & cmd,int stepNdx,int & programFriendlyName,int & resultStorageFriendlyName)1711*35238bceSAndroid Build Coastguard Worker void InterCallTestCase::runCommand(const op::ReadZeroData &cmd, int stepNdx, int &programFriendlyName,
1712*35238bceSAndroid Build Coastguard Worker int &resultStorageFriendlyName)
1713*35238bceSAndroid Build Coastguard Worker {
1714*35238bceSAndroid Build Coastguard Worker runSingleRead(cmd.targetHandle, stepNdx, programFriendlyName, resultStorageFriendlyName);
1715*35238bceSAndroid Build Coastguard Worker }
1716*35238bceSAndroid Build Coastguard Worker
runSingleRead(int targetHandle,int stepNdx,int & programFriendlyName,int & resultStorageFriendlyName)1717*35238bceSAndroid Build Coastguard Worker void InterCallTestCase::runSingleRead(int targetHandle, int stepNdx, int &programFriendlyName,
1718*35238bceSAndroid Build Coastguard Worker int &resultStorageFriendlyName)
1719*35238bceSAndroid Build Coastguard Worker {
1720*35238bceSAndroid Build Coastguard Worker const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1721*35238bceSAndroid Build Coastguard Worker
1722*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Running program #" << ++programFriendlyName << " to verify "
1723*35238bceSAndroid Build Coastguard Worker << ((m_storage == STORAGE_BUFFER) ? ("buffer") : ("image")) << " #" << targetHandle << ".\n"
1724*35238bceSAndroid Build Coastguard Worker << " Writing results to result storage #" << ++resultStorageFriendlyName << ".\n"
1725*35238bceSAndroid Build Coastguard Worker << " Dispatch size: " << m_invocationGridSize << "x" << m_invocationGridSize << "."
1726*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
1727*35238bceSAndroid Build Coastguard Worker
1728*35238bceSAndroid Build Coastguard Worker gl.useProgram(m_operationPrograms[stepNdx]->getProgram());
1729*35238bceSAndroid Build Coastguard Worker
1730*35238bceSAndroid Build Coastguard Worker // set source
1731*35238bceSAndroid Build Coastguard Worker if (m_storage == STORAGE_BUFFER)
1732*35238bceSAndroid Build Coastguard Worker {
1733*35238bceSAndroid Build Coastguard Worker DE_ASSERT(m_storageIDs[targetHandle]);
1734*35238bceSAndroid Build Coastguard Worker
1735*35238bceSAndroid Build Coastguard Worker gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_storageIDs[targetHandle]);
1736*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "bind source buffer");
1737*35238bceSAndroid Build Coastguard Worker }
1738*35238bceSAndroid Build Coastguard Worker else if (m_storage == STORAGE_IMAGE)
1739*35238bceSAndroid Build Coastguard Worker {
1740*35238bceSAndroid Build Coastguard Worker DE_ASSERT(m_storageIDs[targetHandle]);
1741*35238bceSAndroid Build Coastguard Worker
1742*35238bceSAndroid Build Coastguard Worker gl.bindImageTexture(1, m_storageIDs[targetHandle], 0, GL_FALSE, 0,
1743*35238bceSAndroid Build Coastguard Worker (m_useAtomic) ? (GL_READ_WRITE) : (GL_READ_ONLY),
1744*35238bceSAndroid Build Coastguard Worker (m_formatInteger) ? (GL_R32I) : (GL_R32F));
1745*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "bind source image");
1746*35238bceSAndroid Build Coastguard Worker }
1747*35238bceSAndroid Build Coastguard Worker else
1748*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
1749*35238bceSAndroid Build Coastguard Worker
1750*35238bceSAndroid Build Coastguard Worker // set destination
1751*35238bceSAndroid Build Coastguard Worker DE_ASSERT(m_operationResultStorages[stepNdx]);
1752*35238bceSAndroid Build Coastguard Worker gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_operationResultStorages[stepNdx]);
1753*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "bind result buffer");
1754*35238bceSAndroid Build Coastguard Worker
1755*35238bceSAndroid Build Coastguard Worker // calc
1756*35238bceSAndroid Build Coastguard Worker gl.dispatchCompute(m_invocationGridSize, m_invocationGridSize, 1);
1757*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "dispatch read");
1758*35238bceSAndroid Build Coastguard Worker }
1759*35238bceSAndroid Build Coastguard Worker
genStorage(int friendlyName)1760*35238bceSAndroid Build Coastguard Worker glw::GLuint InterCallTestCase::genStorage(int friendlyName)
1761*35238bceSAndroid Build Coastguard Worker {
1762*35238bceSAndroid Build Coastguard Worker const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1763*35238bceSAndroid Build Coastguard Worker
1764*35238bceSAndroid Build Coastguard Worker if (m_storage == STORAGE_BUFFER)
1765*35238bceSAndroid Build Coastguard Worker {
1766*35238bceSAndroid Build Coastguard Worker const int numElements = m_invocationGridSize * m_invocationGridSize * m_perInvocationSize;
1767*35238bceSAndroid Build Coastguard Worker const int bufferSize = numElements * (int)((m_formatInteger) ? (sizeof(int32_t)) : (sizeof(glw::GLfloat)));
1768*35238bceSAndroid Build Coastguard Worker glw::GLuint retVal = 0;
1769*35238bceSAndroid Build Coastguard Worker
1770*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Creating buffer #" << friendlyName << ", size " << bufferSize
1771*35238bceSAndroid Build Coastguard Worker << " bytes." << tcu::TestLog::EndMessage;
1772*35238bceSAndroid Build Coastguard Worker
1773*35238bceSAndroid Build Coastguard Worker gl.genBuffers(1, &retVal);
1774*35238bceSAndroid Build Coastguard Worker gl.bindBuffer(GL_SHADER_STORAGE_BUFFER, retVal);
1775*35238bceSAndroid Build Coastguard Worker
1776*35238bceSAndroid Build Coastguard Worker if (m_formatInteger)
1777*35238bceSAndroid Build Coastguard Worker {
1778*35238bceSAndroid Build Coastguard Worker const std::vector<uint32_t> zeroBuffer(numElements, 0);
1779*35238bceSAndroid Build Coastguard Worker gl.bufferData(GL_SHADER_STORAGE_BUFFER, bufferSize, &zeroBuffer[0], GL_STATIC_DRAW);
1780*35238bceSAndroid Build Coastguard Worker }
1781*35238bceSAndroid Build Coastguard Worker else
1782*35238bceSAndroid Build Coastguard Worker {
1783*35238bceSAndroid Build Coastguard Worker const std::vector<float> zeroBuffer(numElements, 0.0f);
1784*35238bceSAndroid Build Coastguard Worker gl.bufferData(GL_SHADER_STORAGE_BUFFER, bufferSize, &zeroBuffer[0], GL_STATIC_DRAW);
1785*35238bceSAndroid Build Coastguard Worker }
1786*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "gen buffer");
1787*35238bceSAndroid Build Coastguard Worker
1788*35238bceSAndroid Build Coastguard Worker return retVal;
1789*35238bceSAndroid Build Coastguard Worker }
1790*35238bceSAndroid Build Coastguard Worker else if (m_storage == STORAGE_IMAGE)
1791*35238bceSAndroid Build Coastguard Worker {
1792*35238bceSAndroid Build Coastguard Worker const int imageWidth = m_invocationGridSize;
1793*35238bceSAndroid Build Coastguard Worker const int imageHeight = m_invocationGridSize * m_perInvocationSize;
1794*35238bceSAndroid Build Coastguard Worker glw::GLuint retVal = 0;
1795*35238bceSAndroid Build Coastguard Worker
1796*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Creating image #" << friendlyName << ", size " << imageWidth
1797*35238bceSAndroid Build Coastguard Worker << "x" << imageHeight << ", internalformat = " << ((m_formatInteger) ? ("r32i") : ("r32f"))
1798*35238bceSAndroid Build Coastguard Worker << ", size = " << (imageWidth * imageHeight * sizeof(uint32_t)) << " bytes."
1799*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
1800*35238bceSAndroid Build Coastguard Worker
1801*35238bceSAndroid Build Coastguard Worker gl.genTextures(1, &retVal);
1802*35238bceSAndroid Build Coastguard Worker gl.bindTexture(GL_TEXTURE_2D, retVal);
1803*35238bceSAndroid Build Coastguard Worker
1804*35238bceSAndroid Build Coastguard Worker if (m_formatInteger)
1805*35238bceSAndroid Build Coastguard Worker gl.texStorage2D(GL_TEXTURE_2D, 1, GL_R32I, imageWidth, imageHeight);
1806*35238bceSAndroid Build Coastguard Worker else
1807*35238bceSAndroid Build Coastguard Worker gl.texStorage2D(GL_TEXTURE_2D, 1, GL_R32F, imageWidth, imageHeight);
1808*35238bceSAndroid Build Coastguard Worker
1809*35238bceSAndroid Build Coastguard Worker gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1810*35238bceSAndroid Build Coastguard Worker gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1811*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "gen image");
1812*35238bceSAndroid Build Coastguard Worker
1813*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Filling image with 0" << tcu::TestLog::EndMessage;
1814*35238bceSAndroid Build Coastguard Worker
1815*35238bceSAndroid Build Coastguard Worker if (m_formatInteger)
1816*35238bceSAndroid Build Coastguard Worker {
1817*35238bceSAndroid Build Coastguard Worker const std::vector<int32_t> zeroBuffer(imageWidth * imageHeight, 0);
1818*35238bceSAndroid Build Coastguard Worker gl.texSubImage2D(GL_TEXTURE_2D, 0, 0, 0, imageWidth, imageHeight, GL_RED_INTEGER, GL_INT, &zeroBuffer[0]);
1819*35238bceSAndroid Build Coastguard Worker }
1820*35238bceSAndroid Build Coastguard Worker else
1821*35238bceSAndroid Build Coastguard Worker {
1822*35238bceSAndroid Build Coastguard Worker const std::vector<float> zeroBuffer(imageWidth * imageHeight, 0.0f);
1823*35238bceSAndroid Build Coastguard Worker gl.texSubImage2D(GL_TEXTURE_2D, 0, 0, 0, imageWidth, imageHeight, GL_RED, GL_FLOAT, &zeroBuffer[0]);
1824*35238bceSAndroid Build Coastguard Worker }
1825*35238bceSAndroid Build Coastguard Worker
1826*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "specify image contents");
1827*35238bceSAndroid Build Coastguard Worker
1828*35238bceSAndroid Build Coastguard Worker return retVal;
1829*35238bceSAndroid Build Coastguard Worker }
1830*35238bceSAndroid Build Coastguard Worker else
1831*35238bceSAndroid Build Coastguard Worker {
1832*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
1833*35238bceSAndroid Build Coastguard Worker return 0;
1834*35238bceSAndroid Build Coastguard Worker }
1835*35238bceSAndroid Build Coastguard Worker }
1836*35238bceSAndroid Build Coastguard Worker
genResultStorage(void)1837*35238bceSAndroid Build Coastguard Worker glw::GLuint InterCallTestCase::genResultStorage(void)
1838*35238bceSAndroid Build Coastguard Worker {
1839*35238bceSAndroid Build Coastguard Worker const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1840*35238bceSAndroid Build Coastguard Worker glw::GLuint retVal = 0;
1841*35238bceSAndroid Build Coastguard Worker
1842*35238bceSAndroid Build Coastguard Worker gl.genBuffers(1, &retVal);
1843*35238bceSAndroid Build Coastguard Worker gl.bindBuffer(GL_SHADER_STORAGE_BUFFER, retVal);
1844*35238bceSAndroid Build Coastguard Worker gl.bufferData(GL_SHADER_STORAGE_BUFFER, m_invocationGridSize * m_invocationGridSize * sizeof(uint32_t), DE_NULL,
1845*35238bceSAndroid Build Coastguard Worker GL_STATIC_DRAW);
1846*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "gen buffer");
1847*35238bceSAndroid Build Coastguard Worker
1848*35238bceSAndroid Build Coastguard Worker return retVal;
1849*35238bceSAndroid Build Coastguard Worker }
1850*35238bceSAndroid Build Coastguard Worker
genWriteProgram(int seed)1851*35238bceSAndroid Build Coastguard Worker glu::ShaderProgram *InterCallTestCase::genWriteProgram(int seed)
1852*35238bceSAndroid Build Coastguard Worker {
1853*35238bceSAndroid Build Coastguard Worker const bool useImageAtomics = m_useAtomic && m_storage == STORAGE_IMAGE;
1854*35238bceSAndroid Build Coastguard Worker std::ostringstream buf;
1855*35238bceSAndroid Build Coastguard Worker
1856*35238bceSAndroid Build Coastguard Worker buf << "${GLSL_VERSION_DECL}\n"
1857*35238bceSAndroid Build Coastguard Worker << ((useImageAtomics) ? ("${SHADER_IMAGE_ATOMIC_REQUIRE}\n") : (""))
1858*35238bceSAndroid Build Coastguard Worker << "layout (local_size_x = 1, local_size_y = 1) in;\n";
1859*35238bceSAndroid Build Coastguard Worker
1860*35238bceSAndroid Build Coastguard Worker if (m_storage == STORAGE_BUFFER)
1861*35238bceSAndroid Build Coastguard Worker buf << "layout(binding=0, std430) " << ((m_useAtomic) ? ("coherent ") : ("")) << "buffer Buffer\n"
1862*35238bceSAndroid Build Coastguard Worker << "{\n"
1863*35238bceSAndroid Build Coastguard Worker << " highp " << ((m_formatInteger) ? ("int") : ("float")) << " values[];\n"
1864*35238bceSAndroid Build Coastguard Worker << "} sb_out;\n";
1865*35238bceSAndroid Build Coastguard Worker else if (m_storage == STORAGE_IMAGE)
1866*35238bceSAndroid Build Coastguard Worker buf << "layout(" << ((m_formatInteger) ? ("r32i") : ("r32f")) << ", binding=0) "
1867*35238bceSAndroid Build Coastguard Worker << ((m_useAtomic) ? ("coherent ") : ("writeonly ")) << "uniform highp "
1868*35238bceSAndroid Build Coastguard Worker << ((m_formatInteger) ? ("iimage2D") : ("image2D")) << " u_imageOut;\n";
1869*35238bceSAndroid Build Coastguard Worker else
1870*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
1871*35238bceSAndroid Build Coastguard Worker
1872*35238bceSAndroid Build Coastguard Worker buf << "\n"
1873*35238bceSAndroid Build Coastguard Worker << "void main (void)\n"
1874*35238bceSAndroid Build Coastguard Worker << "{\n"
1875*35238bceSAndroid Build Coastguard Worker << " uvec3 size = gl_NumWorkGroups * gl_WorkGroupSize;\n"
1876*35238bceSAndroid Build Coastguard Worker << " int groupNdx = int(size.x * size.y * gl_GlobalInvocationID.z + size.x*gl_GlobalInvocationID.y + "
1877*35238bceSAndroid Build Coastguard Worker "gl_GlobalInvocationID.x);\n"
1878*35238bceSAndroid Build Coastguard Worker << "\n";
1879*35238bceSAndroid Build Coastguard Worker
1880*35238bceSAndroid Build Coastguard Worker // Write to buffer/image m_perInvocationSize elements
1881*35238bceSAndroid Build Coastguard Worker if (m_storage == STORAGE_BUFFER)
1882*35238bceSAndroid Build Coastguard Worker {
1883*35238bceSAndroid Build Coastguard Worker for (int writeNdx = 0; writeNdx < m_perInvocationSize; ++writeNdx)
1884*35238bceSAndroid Build Coastguard Worker {
1885*35238bceSAndroid Build Coastguard Worker if (m_useAtomic)
1886*35238bceSAndroid Build Coastguard Worker buf << " atomicExchange(";
1887*35238bceSAndroid Build Coastguard Worker else
1888*35238bceSAndroid Build Coastguard Worker buf << " ";
1889*35238bceSAndroid Build Coastguard Worker
1890*35238bceSAndroid Build Coastguard Worker buf << "sb_out.values[(groupNdx + " << seed + writeNdx * m_invocationGridSize * m_invocationGridSize
1891*35238bceSAndroid Build Coastguard Worker << ") % " << m_invocationGridSize * m_invocationGridSize * m_perInvocationSize << "]";
1892*35238bceSAndroid Build Coastguard Worker
1893*35238bceSAndroid Build Coastguard Worker if (m_useAtomic)
1894*35238bceSAndroid Build Coastguard Worker buf << ", " << ((m_formatInteger) ? ("int") : ("float")) << "(groupNdx));\n";
1895*35238bceSAndroid Build Coastguard Worker else
1896*35238bceSAndroid Build Coastguard Worker buf << " = " << ((m_formatInteger) ? ("int") : ("float")) << "(groupNdx);\n";
1897*35238bceSAndroid Build Coastguard Worker }
1898*35238bceSAndroid Build Coastguard Worker }
1899*35238bceSAndroid Build Coastguard Worker else if (m_storage == STORAGE_IMAGE)
1900*35238bceSAndroid Build Coastguard Worker {
1901*35238bceSAndroid Build Coastguard Worker for (int writeNdx = 0; writeNdx < m_perInvocationSize; ++writeNdx)
1902*35238bceSAndroid Build Coastguard Worker {
1903*35238bceSAndroid Build Coastguard Worker if (m_useAtomic)
1904*35238bceSAndroid Build Coastguard Worker buf << " imageAtomicExchange";
1905*35238bceSAndroid Build Coastguard Worker else
1906*35238bceSAndroid Build Coastguard Worker buf << " imageStore";
1907*35238bceSAndroid Build Coastguard Worker
1908*35238bceSAndroid Build Coastguard Worker buf << "(u_imageOut, ivec2((int(gl_GlobalInvocationID.x) + " << (seed + writeNdx * 100) << ") % "
1909*35238bceSAndroid Build Coastguard Worker << m_invocationGridSize << ", int(gl_GlobalInvocationID.y) + " << writeNdx * m_invocationGridSize
1910*35238bceSAndroid Build Coastguard Worker << "), ";
1911*35238bceSAndroid Build Coastguard Worker
1912*35238bceSAndroid Build Coastguard Worker if (m_useAtomic)
1913*35238bceSAndroid Build Coastguard Worker buf << ((m_formatInteger) ? ("int") : ("float")) << "(groupNdx));\n";
1914*35238bceSAndroid Build Coastguard Worker else
1915*35238bceSAndroid Build Coastguard Worker buf << ((m_formatInteger) ? ("ivec4(int(groupNdx), 0, 0, 0)") :
1916*35238bceSAndroid Build Coastguard Worker ("vec4(float(groupNdx), 0.0, 0.0, 0.0)"))
1917*35238bceSAndroid Build Coastguard Worker << ");\n";
1918*35238bceSAndroid Build Coastguard Worker }
1919*35238bceSAndroid Build Coastguard Worker }
1920*35238bceSAndroid Build Coastguard Worker else
1921*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
1922*35238bceSAndroid Build Coastguard Worker
1923*35238bceSAndroid Build Coastguard Worker buf << "}\n";
1924*35238bceSAndroid Build Coastguard Worker
1925*35238bceSAndroid Build Coastguard Worker return new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources() << glu::ComputeSource(
1926*35238bceSAndroid Build Coastguard Worker specializeShader(m_context, buf.str().c_str())));
1927*35238bceSAndroid Build Coastguard Worker }
1928*35238bceSAndroid Build Coastguard Worker
genReadProgram(int seed)1929*35238bceSAndroid Build Coastguard Worker glu::ShaderProgram *InterCallTestCase::genReadProgram(int seed)
1930*35238bceSAndroid Build Coastguard Worker {
1931*35238bceSAndroid Build Coastguard Worker const bool useImageAtomics = m_useAtomic && m_storage == STORAGE_IMAGE;
1932*35238bceSAndroid Build Coastguard Worker std::ostringstream buf;
1933*35238bceSAndroid Build Coastguard Worker
1934*35238bceSAndroid Build Coastguard Worker buf << "${GLSL_VERSION_DECL}\n"
1935*35238bceSAndroid Build Coastguard Worker << ((useImageAtomics) ? ("${SHADER_IMAGE_ATOMIC_REQUIRE}\n") : (""))
1936*35238bceSAndroid Build Coastguard Worker << "layout (local_size_x = 1, local_size_y = 1) in;\n";
1937*35238bceSAndroid Build Coastguard Worker
1938*35238bceSAndroid Build Coastguard Worker if (m_storage == STORAGE_BUFFER)
1939*35238bceSAndroid Build Coastguard Worker buf << "layout(binding=1, std430) " << ((m_useAtomic) ? ("coherent ") : ("")) << "buffer Buffer\n"
1940*35238bceSAndroid Build Coastguard Worker << "{\n"
1941*35238bceSAndroid Build Coastguard Worker << " highp " << ((m_formatInteger) ? ("int") : ("float")) << " values[];\n"
1942*35238bceSAndroid Build Coastguard Worker << "} sb_in;\n";
1943*35238bceSAndroid Build Coastguard Worker else if (m_storage == STORAGE_IMAGE)
1944*35238bceSAndroid Build Coastguard Worker buf << "layout(" << ((m_formatInteger) ? ("r32i") : ("r32f")) << ", binding=1) "
1945*35238bceSAndroid Build Coastguard Worker << ((m_useAtomic) ? ("coherent ") : ("readonly ")) << "uniform highp "
1946*35238bceSAndroid Build Coastguard Worker << ((m_formatInteger) ? ("iimage2D") : ("image2D")) << " u_imageIn;\n";
1947*35238bceSAndroid Build Coastguard Worker else
1948*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
1949*35238bceSAndroid Build Coastguard Worker
1950*35238bceSAndroid Build Coastguard Worker buf << "layout(binding=0, std430) buffer ResultBuffer\n"
1951*35238bceSAndroid Build Coastguard Worker << "{\n"
1952*35238bceSAndroid Build Coastguard Worker << " highp int resultOk[];\n"
1953*35238bceSAndroid Build Coastguard Worker << "} sb_result;\n"
1954*35238bceSAndroid Build Coastguard Worker << "\n"
1955*35238bceSAndroid Build Coastguard Worker << "void main (void)\n"
1956*35238bceSAndroid Build Coastguard Worker << "{\n"
1957*35238bceSAndroid Build Coastguard Worker << " uvec3 size = gl_NumWorkGroups * gl_WorkGroupSize;\n"
1958*35238bceSAndroid Build Coastguard Worker << " int groupNdx = int(size.x * size.y * gl_GlobalInvocationID.z + size.x*gl_GlobalInvocationID.y + "
1959*35238bceSAndroid Build Coastguard Worker "gl_GlobalInvocationID.x);\n"
1960*35238bceSAndroid Build Coastguard Worker << " " << ((m_formatInteger) ? ("int") : ("float")) << " zero = " << ((m_formatInteger) ? ("0") : ("0.0"))
1961*35238bceSAndroid Build Coastguard Worker << ";\n"
1962*35238bceSAndroid Build Coastguard Worker << " bool allOk = true;\n"
1963*35238bceSAndroid Build Coastguard Worker << "\n";
1964*35238bceSAndroid Build Coastguard Worker
1965*35238bceSAndroid Build Coastguard Worker // Verify data
1966*35238bceSAndroid Build Coastguard Worker
1967*35238bceSAndroid Build Coastguard Worker if (m_storage == STORAGE_BUFFER)
1968*35238bceSAndroid Build Coastguard Worker {
1969*35238bceSAndroid Build Coastguard Worker for (int readNdx = 0; readNdx < m_perInvocationSize; ++readNdx)
1970*35238bceSAndroid Build Coastguard Worker {
1971*35238bceSAndroid Build Coastguard Worker if (!m_useAtomic)
1972*35238bceSAndroid Build Coastguard Worker buf << " allOk = allOk && (sb_in.values[(groupNdx + "
1973*35238bceSAndroid Build Coastguard Worker << seed + readNdx * m_invocationGridSize * m_invocationGridSize << ") % "
1974*35238bceSAndroid Build Coastguard Worker << m_invocationGridSize * m_invocationGridSize * m_perInvocationSize
1975*35238bceSAndroid Build Coastguard Worker << "] == " << ((m_formatInteger) ? ("int") : ("float")) << "(groupNdx));\n";
1976*35238bceSAndroid Build Coastguard Worker else
1977*35238bceSAndroid Build Coastguard Worker buf << " allOk = allOk && (atomicExchange(sb_in.values[(groupNdx + "
1978*35238bceSAndroid Build Coastguard Worker << seed + readNdx * m_invocationGridSize * m_invocationGridSize << ") % "
1979*35238bceSAndroid Build Coastguard Worker << m_invocationGridSize * m_invocationGridSize * m_perInvocationSize
1980*35238bceSAndroid Build Coastguard Worker << "], zero) == " << ((m_formatInteger) ? ("int") : ("float")) << "(groupNdx));\n";
1981*35238bceSAndroid Build Coastguard Worker }
1982*35238bceSAndroid Build Coastguard Worker }
1983*35238bceSAndroid Build Coastguard Worker else if (m_storage == STORAGE_IMAGE)
1984*35238bceSAndroid Build Coastguard Worker {
1985*35238bceSAndroid Build Coastguard Worker for (int readNdx = 0; readNdx < m_perInvocationSize; ++readNdx)
1986*35238bceSAndroid Build Coastguard Worker {
1987*35238bceSAndroid Build Coastguard Worker if (!m_useAtomic)
1988*35238bceSAndroid Build Coastguard Worker buf << " allOk = allOk && (imageLoad(u_imageIn, ivec2((gl_GlobalInvocationID.x + "
1989*35238bceSAndroid Build Coastguard Worker << (seed + readNdx * 100) << "u) % " << m_invocationGridSize << "u, gl_GlobalInvocationID.y + "
1990*35238bceSAndroid Build Coastguard Worker << readNdx * m_invocationGridSize << "u)).x == " << ((m_formatInteger) ? ("int") : ("float"))
1991*35238bceSAndroid Build Coastguard Worker << "(groupNdx));\n";
1992*35238bceSAndroid Build Coastguard Worker else
1993*35238bceSAndroid Build Coastguard Worker buf << " allOk = allOk && (imageAtomicExchange(u_imageIn, ivec2((gl_GlobalInvocationID.x + "
1994*35238bceSAndroid Build Coastguard Worker << (seed + readNdx * 100) << "u) % " << m_invocationGridSize << "u, gl_GlobalInvocationID.y + "
1995*35238bceSAndroid Build Coastguard Worker << readNdx * m_invocationGridSize << "u), zero) == " << ((m_formatInteger) ? ("int") : ("float"))
1996*35238bceSAndroid Build Coastguard Worker << "(groupNdx));\n";
1997*35238bceSAndroid Build Coastguard Worker }
1998*35238bceSAndroid Build Coastguard Worker }
1999*35238bceSAndroid Build Coastguard Worker else
2000*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
2001*35238bceSAndroid Build Coastguard Worker
2002*35238bceSAndroid Build Coastguard Worker buf << " sb_result.resultOk[groupNdx] = (allOk) ? (1) : (0);\n"
2003*35238bceSAndroid Build Coastguard Worker << "}\n";
2004*35238bceSAndroid Build Coastguard Worker
2005*35238bceSAndroid Build Coastguard Worker return new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources() << glu::ComputeSource(
2006*35238bceSAndroid Build Coastguard Worker specializeShader(m_context, buf.str().c_str())));
2007*35238bceSAndroid Build Coastguard Worker }
2008*35238bceSAndroid Build Coastguard Worker
genReadMultipleProgram(int seed0,int seed1)2009*35238bceSAndroid Build Coastguard Worker glu::ShaderProgram *InterCallTestCase::genReadMultipleProgram(int seed0, int seed1)
2010*35238bceSAndroid Build Coastguard Worker {
2011*35238bceSAndroid Build Coastguard Worker const bool useImageAtomics = m_useAtomic && m_storage == STORAGE_IMAGE;
2012*35238bceSAndroid Build Coastguard Worker std::ostringstream buf;
2013*35238bceSAndroid Build Coastguard Worker
2014*35238bceSAndroid Build Coastguard Worker buf << "${GLSL_VERSION_DECL}\n"
2015*35238bceSAndroid Build Coastguard Worker << ((useImageAtomics) ? ("${SHADER_IMAGE_ATOMIC_REQUIRE}\n") : (""))
2016*35238bceSAndroid Build Coastguard Worker << "layout (local_size_x = 1, local_size_y = 1) in;\n";
2017*35238bceSAndroid Build Coastguard Worker
2018*35238bceSAndroid Build Coastguard Worker if (m_storage == STORAGE_BUFFER)
2019*35238bceSAndroid Build Coastguard Worker buf << "layout(binding=1, std430) " << ((m_useAtomic) ? ("coherent ") : ("")) << "buffer Buffer0\n"
2020*35238bceSAndroid Build Coastguard Worker << "{\n"
2021*35238bceSAndroid Build Coastguard Worker << " highp " << ((m_formatInteger) ? ("int") : ("float")) << " values[];\n"
2022*35238bceSAndroid Build Coastguard Worker << "} sb_in0;\n"
2023*35238bceSAndroid Build Coastguard Worker << "layout(binding=2, std430) " << ((m_useAtomic) ? ("coherent ") : ("")) << "buffer Buffer1\n"
2024*35238bceSAndroid Build Coastguard Worker << "{\n"
2025*35238bceSAndroid Build Coastguard Worker << " highp " << ((m_formatInteger) ? ("int") : ("float")) << " values[];\n"
2026*35238bceSAndroid Build Coastguard Worker << "} sb_in1;\n";
2027*35238bceSAndroid Build Coastguard Worker else if (m_storage == STORAGE_IMAGE)
2028*35238bceSAndroid Build Coastguard Worker buf << "layout(" << ((m_formatInteger) ? ("r32i") : ("r32f")) << ", binding=1) "
2029*35238bceSAndroid Build Coastguard Worker << ((m_useAtomic) ? ("coherent ") : ("readonly ")) << "uniform highp "
2030*35238bceSAndroid Build Coastguard Worker << ((m_formatInteger) ? ("iimage2D") : ("image2D")) << " u_imageIn0;\n"
2031*35238bceSAndroid Build Coastguard Worker << "layout(" << ((m_formatInteger) ? ("r32i") : ("r32f")) << ", binding=2) "
2032*35238bceSAndroid Build Coastguard Worker << ((m_useAtomic) ? ("coherent ") : ("readonly ")) << "uniform highp "
2033*35238bceSAndroid Build Coastguard Worker << ((m_formatInteger) ? ("iimage2D") : ("image2D")) << " u_imageIn1;\n";
2034*35238bceSAndroid Build Coastguard Worker else
2035*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
2036*35238bceSAndroid Build Coastguard Worker
2037*35238bceSAndroid Build Coastguard Worker buf << "layout(binding=0, std430) buffer ResultBuffer\n"
2038*35238bceSAndroid Build Coastguard Worker << "{\n"
2039*35238bceSAndroid Build Coastguard Worker << " highp int resultOk[];\n"
2040*35238bceSAndroid Build Coastguard Worker << "} sb_result;\n"
2041*35238bceSAndroid Build Coastguard Worker << "\n"
2042*35238bceSAndroid Build Coastguard Worker << "void main (void)\n"
2043*35238bceSAndroid Build Coastguard Worker << "{\n"
2044*35238bceSAndroid Build Coastguard Worker << " uvec3 size = gl_NumWorkGroups * gl_WorkGroupSize;\n"
2045*35238bceSAndroid Build Coastguard Worker << " int groupNdx = int(size.x * size.y * gl_GlobalInvocationID.z + size.x*gl_GlobalInvocationID.y + "
2046*35238bceSAndroid Build Coastguard Worker "gl_GlobalInvocationID.x);\n"
2047*35238bceSAndroid Build Coastguard Worker << " " << ((m_formatInteger) ? ("int") : ("float")) << " zero = " << ((m_formatInteger) ? ("0") : ("0.0"))
2048*35238bceSAndroid Build Coastguard Worker << ";\n"
2049*35238bceSAndroid Build Coastguard Worker << " bool allOk = true;\n"
2050*35238bceSAndroid Build Coastguard Worker << "\n";
2051*35238bceSAndroid Build Coastguard Worker
2052*35238bceSAndroid Build Coastguard Worker // Verify data
2053*35238bceSAndroid Build Coastguard Worker
2054*35238bceSAndroid Build Coastguard Worker if (m_storage == STORAGE_BUFFER)
2055*35238bceSAndroid Build Coastguard Worker {
2056*35238bceSAndroid Build Coastguard Worker for (int readNdx = 0; readNdx < m_perInvocationSize; ++readNdx)
2057*35238bceSAndroid Build Coastguard Worker buf << " allOk = allOk && (" << ((m_useAtomic) ? ("atomicExchange(") : (""))
2058*35238bceSAndroid Build Coastguard Worker << "sb_in0.values[(groupNdx + " << seed0 + readNdx * m_invocationGridSize * m_invocationGridSize
2059*35238bceSAndroid Build Coastguard Worker << ") % " << m_invocationGridSize * m_invocationGridSize * m_perInvocationSize << "]"
2060*35238bceSAndroid Build Coastguard Worker << ((m_useAtomic) ? (", zero)") : ("")) << " == " << ((m_formatInteger) ? ("int") : ("float"))
2061*35238bceSAndroid Build Coastguard Worker << "(groupNdx));\n"
2062*35238bceSAndroid Build Coastguard Worker << " allOk = allOk && (" << ((m_useAtomic) ? ("atomicExchange(") : (""))
2063*35238bceSAndroid Build Coastguard Worker << "sb_in1.values[(groupNdx + " << seed1 + readNdx * m_invocationGridSize * m_invocationGridSize
2064*35238bceSAndroid Build Coastguard Worker << ") % " << m_invocationGridSize * m_invocationGridSize * m_perInvocationSize << "]"
2065*35238bceSAndroid Build Coastguard Worker << ((m_useAtomic) ? (", zero)") : ("")) << " == " << ((m_formatInteger) ? ("int") : ("float"))
2066*35238bceSAndroid Build Coastguard Worker << "(groupNdx));\n";
2067*35238bceSAndroid Build Coastguard Worker }
2068*35238bceSAndroid Build Coastguard Worker else if (m_storage == STORAGE_IMAGE)
2069*35238bceSAndroid Build Coastguard Worker {
2070*35238bceSAndroid Build Coastguard Worker for (int readNdx = 0; readNdx < m_perInvocationSize; ++readNdx)
2071*35238bceSAndroid Build Coastguard Worker buf << " allOk = allOk && (" << ((m_useAtomic) ? ("imageAtomicExchange") : ("imageLoad"))
2072*35238bceSAndroid Build Coastguard Worker << "(u_imageIn0, ivec2((gl_GlobalInvocationID.x + " << (seed0 + readNdx * 100) << "u) % "
2073*35238bceSAndroid Build Coastguard Worker << m_invocationGridSize << "u, gl_GlobalInvocationID.y + " << readNdx * m_invocationGridSize << "u)"
2074*35238bceSAndroid Build Coastguard Worker << ((m_useAtomic) ? (", zero)") : (").x")) << " == " << ((m_formatInteger) ? ("int") : ("float"))
2075*35238bceSAndroid Build Coastguard Worker << "(groupNdx));\n"
2076*35238bceSAndroid Build Coastguard Worker << " allOk = allOk && (" << ((m_useAtomic) ? ("imageAtomicExchange") : ("imageLoad"))
2077*35238bceSAndroid Build Coastguard Worker << "(u_imageIn1, ivec2((gl_GlobalInvocationID.x + " << (seed1 + readNdx * 100) << "u) % "
2078*35238bceSAndroid Build Coastguard Worker << m_invocationGridSize << "u, gl_GlobalInvocationID.y + " << readNdx * m_invocationGridSize << "u)"
2079*35238bceSAndroid Build Coastguard Worker << ((m_useAtomic) ? (", zero)") : (").x")) << " == " << ((m_formatInteger) ? ("int") : ("float"))
2080*35238bceSAndroid Build Coastguard Worker << "(groupNdx));\n";
2081*35238bceSAndroid Build Coastguard Worker }
2082*35238bceSAndroid Build Coastguard Worker else
2083*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
2084*35238bceSAndroid Build Coastguard Worker
2085*35238bceSAndroid Build Coastguard Worker buf << " sb_result.resultOk[groupNdx] = (allOk) ? (1) : (0);\n"
2086*35238bceSAndroid Build Coastguard Worker << "}\n";
2087*35238bceSAndroid Build Coastguard Worker
2088*35238bceSAndroid Build Coastguard Worker return new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources() << glu::ComputeSource(
2089*35238bceSAndroid Build Coastguard Worker specializeShader(m_context, buf.str().c_str())));
2090*35238bceSAndroid Build Coastguard Worker }
2091*35238bceSAndroid Build Coastguard Worker
genWriteInterleavedProgram(int seed,bool evenOdd)2092*35238bceSAndroid Build Coastguard Worker glu::ShaderProgram *InterCallTestCase::genWriteInterleavedProgram(int seed, bool evenOdd)
2093*35238bceSAndroid Build Coastguard Worker {
2094*35238bceSAndroid Build Coastguard Worker const bool useImageAtomics = m_useAtomic && m_storage == STORAGE_IMAGE;
2095*35238bceSAndroid Build Coastguard Worker std::ostringstream buf;
2096*35238bceSAndroid Build Coastguard Worker
2097*35238bceSAndroid Build Coastguard Worker buf << "${GLSL_VERSION_DECL}\n"
2098*35238bceSAndroid Build Coastguard Worker << ((useImageAtomics) ? ("${SHADER_IMAGE_ATOMIC_REQUIRE}\n") : (""))
2099*35238bceSAndroid Build Coastguard Worker << "layout (local_size_x = 1, local_size_y = 1) in;\n";
2100*35238bceSAndroid Build Coastguard Worker
2101*35238bceSAndroid Build Coastguard Worker if (m_storage == STORAGE_BUFFER)
2102*35238bceSAndroid Build Coastguard Worker buf << "layout(binding=0, std430) " << ((m_useAtomic) ? ("coherent ") : ("")) << "buffer Buffer\n"
2103*35238bceSAndroid Build Coastguard Worker << "{\n"
2104*35238bceSAndroid Build Coastguard Worker << " highp " << ((m_formatInteger) ? ("int") : ("float")) << " values[];\n"
2105*35238bceSAndroid Build Coastguard Worker << "} sb_out;\n";
2106*35238bceSAndroid Build Coastguard Worker else if (m_storage == STORAGE_IMAGE)
2107*35238bceSAndroid Build Coastguard Worker buf << "layout(" << ((m_formatInteger) ? ("r32i") : ("r32f")) << ", binding=0) "
2108*35238bceSAndroid Build Coastguard Worker << ((m_useAtomic) ? ("coherent ") : ("writeonly ")) << "uniform highp "
2109*35238bceSAndroid Build Coastguard Worker << ((m_formatInteger) ? ("iimage2D") : ("image2D")) << " u_imageOut;\n";
2110*35238bceSAndroid Build Coastguard Worker else
2111*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
2112*35238bceSAndroid Build Coastguard Worker
2113*35238bceSAndroid Build Coastguard Worker buf << "\n"
2114*35238bceSAndroid Build Coastguard Worker << "void main (void)\n"
2115*35238bceSAndroid Build Coastguard Worker << "{\n"
2116*35238bceSAndroid Build Coastguard Worker << " uvec3 size = gl_NumWorkGroups * gl_WorkGroupSize;\n"
2117*35238bceSAndroid Build Coastguard Worker << " int groupNdx = int(size.x * size.y * gl_GlobalInvocationID.z + size.x*gl_GlobalInvocationID.y + "
2118*35238bceSAndroid Build Coastguard Worker "gl_GlobalInvocationID.x);\n"
2119*35238bceSAndroid Build Coastguard Worker << "\n";
2120*35238bceSAndroid Build Coastguard Worker
2121*35238bceSAndroid Build Coastguard Worker // Write to buffer/image m_perInvocationSize elements
2122*35238bceSAndroid Build Coastguard Worker if (m_storage == STORAGE_BUFFER)
2123*35238bceSAndroid Build Coastguard Worker {
2124*35238bceSAndroid Build Coastguard Worker for (int writeNdx = 0; writeNdx < m_perInvocationSize; ++writeNdx)
2125*35238bceSAndroid Build Coastguard Worker {
2126*35238bceSAndroid Build Coastguard Worker if (m_useAtomic)
2127*35238bceSAndroid Build Coastguard Worker buf << " atomicExchange(";
2128*35238bceSAndroid Build Coastguard Worker else
2129*35238bceSAndroid Build Coastguard Worker buf << " ";
2130*35238bceSAndroid Build Coastguard Worker
2131*35238bceSAndroid Build Coastguard Worker buf << "sb_out.values[((groupNdx + " << seed + writeNdx * m_invocationGridSize * m_invocationGridSize / 2
2132*35238bceSAndroid Build Coastguard Worker << ") % " << m_invocationGridSize * m_invocationGridSize / 2 * m_perInvocationSize << ") * 2 + "
2133*35238bceSAndroid Build Coastguard Worker << ((evenOdd) ? (0) : (1)) << "]";
2134*35238bceSAndroid Build Coastguard Worker
2135*35238bceSAndroid Build Coastguard Worker if (m_useAtomic)
2136*35238bceSAndroid Build Coastguard Worker buf << ", " << ((m_formatInteger) ? ("int") : ("float")) << "(groupNdx));\n";
2137*35238bceSAndroid Build Coastguard Worker else
2138*35238bceSAndroid Build Coastguard Worker buf << "= " << ((m_formatInteger) ? ("int") : ("float")) << "(groupNdx);\n";
2139*35238bceSAndroid Build Coastguard Worker }
2140*35238bceSAndroid Build Coastguard Worker }
2141*35238bceSAndroid Build Coastguard Worker else if (m_storage == STORAGE_IMAGE)
2142*35238bceSAndroid Build Coastguard Worker {
2143*35238bceSAndroid Build Coastguard Worker for (int writeNdx = 0; writeNdx < m_perInvocationSize; ++writeNdx)
2144*35238bceSAndroid Build Coastguard Worker {
2145*35238bceSAndroid Build Coastguard Worker if (m_useAtomic)
2146*35238bceSAndroid Build Coastguard Worker buf << " imageAtomicExchange";
2147*35238bceSAndroid Build Coastguard Worker else
2148*35238bceSAndroid Build Coastguard Worker buf << " imageStore";
2149*35238bceSAndroid Build Coastguard Worker
2150*35238bceSAndroid Build Coastguard Worker buf << "(u_imageOut, ivec2(((int(gl_GlobalInvocationID.x) + " << (seed + writeNdx * 100) << ") % "
2151*35238bceSAndroid Build Coastguard Worker << m_invocationGridSize / 2 << ") * 2 + " << ((evenOdd) ? (0) : (1))
2152*35238bceSAndroid Build Coastguard Worker << ", int(gl_GlobalInvocationID.y) + " << writeNdx * m_invocationGridSize << "), ";
2153*35238bceSAndroid Build Coastguard Worker
2154*35238bceSAndroid Build Coastguard Worker if (m_useAtomic)
2155*35238bceSAndroid Build Coastguard Worker buf << ((m_formatInteger) ? ("int") : ("float")) << "(groupNdx));\n";
2156*35238bceSAndroid Build Coastguard Worker else
2157*35238bceSAndroid Build Coastguard Worker buf << ((m_formatInteger) ? ("ivec4(int(groupNdx), 0, 0, 0)") :
2158*35238bceSAndroid Build Coastguard Worker ("vec4(float(groupNdx), 0.0, 0.0, 0.0)"))
2159*35238bceSAndroid Build Coastguard Worker << ");\n";
2160*35238bceSAndroid Build Coastguard Worker }
2161*35238bceSAndroid Build Coastguard Worker }
2162*35238bceSAndroid Build Coastguard Worker else
2163*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
2164*35238bceSAndroid Build Coastguard Worker
2165*35238bceSAndroid Build Coastguard Worker buf << "}\n";
2166*35238bceSAndroid Build Coastguard Worker
2167*35238bceSAndroid Build Coastguard Worker return new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources() << glu::ComputeSource(
2168*35238bceSAndroid Build Coastguard Worker specializeShader(m_context, buf.str().c_str())));
2169*35238bceSAndroid Build Coastguard Worker }
2170*35238bceSAndroid Build Coastguard Worker
genReadInterleavedProgram(int seed0,int seed1)2171*35238bceSAndroid Build Coastguard Worker glu::ShaderProgram *InterCallTestCase::genReadInterleavedProgram(int seed0, int seed1)
2172*35238bceSAndroid Build Coastguard Worker {
2173*35238bceSAndroid Build Coastguard Worker const bool useImageAtomics = m_useAtomic && m_storage == STORAGE_IMAGE;
2174*35238bceSAndroid Build Coastguard Worker std::ostringstream buf;
2175*35238bceSAndroid Build Coastguard Worker
2176*35238bceSAndroid Build Coastguard Worker buf << "${GLSL_VERSION_DECL}\n"
2177*35238bceSAndroid Build Coastguard Worker << ((useImageAtomics) ? ("${SHADER_IMAGE_ATOMIC_REQUIRE}\n") : (""))
2178*35238bceSAndroid Build Coastguard Worker << "layout (local_size_x = 1, local_size_y = 1) in;\n";
2179*35238bceSAndroid Build Coastguard Worker
2180*35238bceSAndroid Build Coastguard Worker if (m_storage == STORAGE_BUFFER)
2181*35238bceSAndroid Build Coastguard Worker buf << "layout(binding=1, std430) " << ((m_useAtomic) ? ("coherent ") : ("")) << "buffer Buffer\n"
2182*35238bceSAndroid Build Coastguard Worker << "{\n"
2183*35238bceSAndroid Build Coastguard Worker << " highp " << ((m_formatInteger) ? ("int") : ("float")) << " values[];\n"
2184*35238bceSAndroid Build Coastguard Worker << "} sb_in;\n";
2185*35238bceSAndroid Build Coastguard Worker else if (m_storage == STORAGE_IMAGE)
2186*35238bceSAndroid Build Coastguard Worker buf << "layout(" << ((m_formatInteger) ? ("r32i") : ("r32f")) << ", binding=1) "
2187*35238bceSAndroid Build Coastguard Worker << ((m_useAtomic) ? ("coherent ") : ("readonly ")) << "uniform highp "
2188*35238bceSAndroid Build Coastguard Worker << ((m_formatInteger) ? ("iimage2D") : ("image2D")) << " u_imageIn;\n";
2189*35238bceSAndroid Build Coastguard Worker else
2190*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
2191*35238bceSAndroid Build Coastguard Worker
2192*35238bceSAndroid Build Coastguard Worker buf << "layout(binding=0, std430) buffer ResultBuffer\n"
2193*35238bceSAndroid Build Coastguard Worker << "{\n"
2194*35238bceSAndroid Build Coastguard Worker << " highp int resultOk[];\n"
2195*35238bceSAndroid Build Coastguard Worker << "} sb_result;\n"
2196*35238bceSAndroid Build Coastguard Worker << "\n"
2197*35238bceSAndroid Build Coastguard Worker << "void main (void)\n"
2198*35238bceSAndroid Build Coastguard Worker << "{\n"
2199*35238bceSAndroid Build Coastguard Worker << " uvec3 size = gl_NumWorkGroups * gl_WorkGroupSize;\n"
2200*35238bceSAndroid Build Coastguard Worker << " int groupNdx = int(size.x * size.y * gl_GlobalInvocationID.z + size.x*gl_GlobalInvocationID.y + "
2201*35238bceSAndroid Build Coastguard Worker "gl_GlobalInvocationID.x);\n"
2202*35238bceSAndroid Build Coastguard Worker << " int interleavedGroupNdx = int((size.x >> 1U) * size.y * gl_GlobalInvocationID.z + (size.x >> 1U) * "
2203*35238bceSAndroid Build Coastguard Worker "gl_GlobalInvocationID.y + (gl_GlobalInvocationID.x >> 1U));\n"
2204*35238bceSAndroid Build Coastguard Worker << " " << ((m_formatInteger) ? ("int") : ("float")) << " zero = " << ((m_formatInteger) ? ("0") : ("0.0"))
2205*35238bceSAndroid Build Coastguard Worker << ";\n"
2206*35238bceSAndroid Build Coastguard Worker << " bool allOk = true;\n"
2207*35238bceSAndroid Build Coastguard Worker << "\n";
2208*35238bceSAndroid Build Coastguard Worker
2209*35238bceSAndroid Build Coastguard Worker // Verify data
2210*35238bceSAndroid Build Coastguard Worker
2211*35238bceSAndroid Build Coastguard Worker if (m_storage == STORAGE_BUFFER)
2212*35238bceSAndroid Build Coastguard Worker {
2213*35238bceSAndroid Build Coastguard Worker buf << " if (groupNdx % 2 == 0)\n"
2214*35238bceSAndroid Build Coastguard Worker << " {\n";
2215*35238bceSAndroid Build Coastguard Worker for (int readNdx = 0; readNdx < m_perInvocationSize; ++readNdx)
2216*35238bceSAndroid Build Coastguard Worker buf << " allOk = allOk && (" << ((m_useAtomic) ? ("atomicExchange(") : (""))
2217*35238bceSAndroid Build Coastguard Worker << "sb_in.values[((interleavedGroupNdx + "
2218*35238bceSAndroid Build Coastguard Worker << seed0 + readNdx * m_invocationGridSize * m_invocationGridSize / 2 << ") % "
2219*35238bceSAndroid Build Coastguard Worker << m_invocationGridSize * m_invocationGridSize * m_perInvocationSize / 2 << ") * 2 + 0]"
2220*35238bceSAndroid Build Coastguard Worker << ((m_useAtomic) ? (", zero)") : ("")) << " == " << ((m_formatInteger) ? ("int") : ("float"))
2221*35238bceSAndroid Build Coastguard Worker << "(interleavedGroupNdx));\n";
2222*35238bceSAndroid Build Coastguard Worker buf << " }\n"
2223*35238bceSAndroid Build Coastguard Worker << " else\n"
2224*35238bceSAndroid Build Coastguard Worker << " {\n";
2225*35238bceSAndroid Build Coastguard Worker for (int readNdx = 0; readNdx < m_perInvocationSize; ++readNdx)
2226*35238bceSAndroid Build Coastguard Worker buf << " allOk = allOk && (" << ((m_useAtomic) ? ("atomicExchange(") : (""))
2227*35238bceSAndroid Build Coastguard Worker << "sb_in.values[((interleavedGroupNdx + "
2228*35238bceSAndroid Build Coastguard Worker << seed1 + readNdx * m_invocationGridSize * m_invocationGridSize / 2 << ") % "
2229*35238bceSAndroid Build Coastguard Worker << m_invocationGridSize * m_invocationGridSize * m_perInvocationSize / 2 << ") * 2 + 1]"
2230*35238bceSAndroid Build Coastguard Worker << ((m_useAtomic) ? (", zero)") : ("")) << " == " << ((m_formatInteger) ? ("int") : ("float"))
2231*35238bceSAndroid Build Coastguard Worker << "(interleavedGroupNdx));\n";
2232*35238bceSAndroid Build Coastguard Worker buf << " }\n";
2233*35238bceSAndroid Build Coastguard Worker }
2234*35238bceSAndroid Build Coastguard Worker else if (m_storage == STORAGE_IMAGE)
2235*35238bceSAndroid Build Coastguard Worker {
2236*35238bceSAndroid Build Coastguard Worker buf << " if (groupNdx % 2 == 0)\n"
2237*35238bceSAndroid Build Coastguard Worker << " {\n";
2238*35238bceSAndroid Build Coastguard Worker for (int readNdx = 0; readNdx < m_perInvocationSize; ++readNdx)
2239*35238bceSAndroid Build Coastguard Worker buf << " allOk = allOk && (" << ((m_useAtomic) ? ("imageAtomicExchange") : ("imageLoad"))
2240*35238bceSAndroid Build Coastguard Worker << "(u_imageIn, ivec2(((int(gl_GlobalInvocationID.x >> 1U) + " << (seed0 + readNdx * 100) << ") % "
2241*35238bceSAndroid Build Coastguard Worker << m_invocationGridSize / 2 << ") * 2 + 0, int(gl_GlobalInvocationID.y) + "
2242*35238bceSAndroid Build Coastguard Worker << readNdx * m_invocationGridSize << ")" << ((m_useAtomic) ? (", zero)") : (").x"))
2243*35238bceSAndroid Build Coastguard Worker << " == " << ((m_formatInteger) ? ("int") : ("float")) << "(interleavedGroupNdx));\n";
2244*35238bceSAndroid Build Coastguard Worker buf << " }\n"
2245*35238bceSAndroid Build Coastguard Worker << " else\n"
2246*35238bceSAndroid Build Coastguard Worker << " {\n";
2247*35238bceSAndroid Build Coastguard Worker for (int readNdx = 0; readNdx < m_perInvocationSize; ++readNdx)
2248*35238bceSAndroid Build Coastguard Worker buf << " allOk = allOk && (" << ((m_useAtomic) ? ("imageAtomicExchange") : ("imageLoad"))
2249*35238bceSAndroid Build Coastguard Worker << "(u_imageIn, ivec2(((int(gl_GlobalInvocationID.x >> 1U) + " << (seed1 + readNdx * 100) << ") % "
2250*35238bceSAndroid Build Coastguard Worker << m_invocationGridSize / 2 << ") * 2 + 1, int(gl_GlobalInvocationID.y) + "
2251*35238bceSAndroid Build Coastguard Worker << readNdx * m_invocationGridSize << ")" << ((m_useAtomic) ? (", zero)") : (").x"))
2252*35238bceSAndroid Build Coastguard Worker << " == " << ((m_formatInteger) ? ("int") : ("float")) << "(interleavedGroupNdx));\n";
2253*35238bceSAndroid Build Coastguard Worker buf << " }\n";
2254*35238bceSAndroid Build Coastguard Worker }
2255*35238bceSAndroid Build Coastguard Worker else
2256*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
2257*35238bceSAndroid Build Coastguard Worker
2258*35238bceSAndroid Build Coastguard Worker buf << " sb_result.resultOk[groupNdx] = (allOk) ? (1) : (0);\n"
2259*35238bceSAndroid Build Coastguard Worker << "}\n";
2260*35238bceSAndroid Build Coastguard Worker
2261*35238bceSAndroid Build Coastguard Worker return new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources() << glu::ComputeSource(
2262*35238bceSAndroid Build Coastguard Worker specializeShader(m_context, buf.str().c_str())));
2263*35238bceSAndroid Build Coastguard Worker }
2264*35238bceSAndroid Build Coastguard Worker
genReadZeroProgram(void)2265*35238bceSAndroid Build Coastguard Worker glu::ShaderProgram *InterCallTestCase::genReadZeroProgram(void)
2266*35238bceSAndroid Build Coastguard Worker {
2267*35238bceSAndroid Build Coastguard Worker const bool useImageAtomics = m_useAtomic && m_storage == STORAGE_IMAGE;
2268*35238bceSAndroid Build Coastguard Worker std::ostringstream buf;
2269*35238bceSAndroid Build Coastguard Worker
2270*35238bceSAndroid Build Coastguard Worker buf << "${GLSL_VERSION_DECL}\n"
2271*35238bceSAndroid Build Coastguard Worker << ((useImageAtomics) ? ("${SHADER_IMAGE_ATOMIC_REQUIRE}\n") : (""))
2272*35238bceSAndroid Build Coastguard Worker << "layout (local_size_x = 1, local_size_y = 1) in;\n";
2273*35238bceSAndroid Build Coastguard Worker
2274*35238bceSAndroid Build Coastguard Worker if (m_storage == STORAGE_BUFFER)
2275*35238bceSAndroid Build Coastguard Worker buf << "layout(binding=1, std430) " << ((m_useAtomic) ? ("coherent ") : ("")) << "buffer Buffer\n"
2276*35238bceSAndroid Build Coastguard Worker << "{\n"
2277*35238bceSAndroid Build Coastguard Worker << " highp " << ((m_formatInteger) ? ("int") : ("float")) << " values[];\n"
2278*35238bceSAndroid Build Coastguard Worker << "} sb_in;\n";
2279*35238bceSAndroid Build Coastguard Worker else if (m_storage == STORAGE_IMAGE)
2280*35238bceSAndroid Build Coastguard Worker buf << "layout(" << ((m_formatInteger) ? ("r32i") : ("r32f")) << ", binding=1) "
2281*35238bceSAndroid Build Coastguard Worker << ((m_useAtomic) ? ("coherent ") : ("readonly ")) << "uniform highp "
2282*35238bceSAndroid Build Coastguard Worker << ((m_formatInteger) ? ("iimage2D") : ("image2D")) << " u_imageIn;\n";
2283*35238bceSAndroid Build Coastguard Worker else
2284*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
2285*35238bceSAndroid Build Coastguard Worker
2286*35238bceSAndroid Build Coastguard Worker buf << "layout(binding=0, std430) buffer ResultBuffer\n"
2287*35238bceSAndroid Build Coastguard Worker << "{\n"
2288*35238bceSAndroid Build Coastguard Worker << " highp int resultOk[];\n"
2289*35238bceSAndroid Build Coastguard Worker << "} sb_result;\n"
2290*35238bceSAndroid Build Coastguard Worker << "\n"
2291*35238bceSAndroid Build Coastguard Worker << "void main (void)\n"
2292*35238bceSAndroid Build Coastguard Worker << "{\n"
2293*35238bceSAndroid Build Coastguard Worker << " uvec3 size = gl_NumWorkGroups * gl_WorkGroupSize;\n"
2294*35238bceSAndroid Build Coastguard Worker << " int groupNdx = int(size.x * size.y * gl_GlobalInvocationID.z + size.x*gl_GlobalInvocationID.y + "
2295*35238bceSAndroid Build Coastguard Worker "gl_GlobalInvocationID.x);\n"
2296*35238bceSAndroid Build Coastguard Worker << " " << ((m_formatInteger) ? ("int") : ("float"))
2297*35238bceSAndroid Build Coastguard Worker << " anything = " << ((m_formatInteger) ? ("5") : ("5.0")) << ";\n"
2298*35238bceSAndroid Build Coastguard Worker << " bool allOk = true;\n"
2299*35238bceSAndroid Build Coastguard Worker << "\n";
2300*35238bceSAndroid Build Coastguard Worker
2301*35238bceSAndroid Build Coastguard Worker // Verify data
2302*35238bceSAndroid Build Coastguard Worker
2303*35238bceSAndroid Build Coastguard Worker if (m_storage == STORAGE_BUFFER)
2304*35238bceSAndroid Build Coastguard Worker {
2305*35238bceSAndroid Build Coastguard Worker for (int readNdx = 0; readNdx < m_perInvocationSize; ++readNdx)
2306*35238bceSAndroid Build Coastguard Worker buf << " allOk = allOk && (" << ((m_useAtomic) ? ("atomicExchange(") : (""))
2307*35238bceSAndroid Build Coastguard Worker << "sb_in.values[groupNdx * " << m_perInvocationSize << " + " << readNdx << "]"
2308*35238bceSAndroid Build Coastguard Worker << ((m_useAtomic) ? (", anything)") : ("")) << " == " << ((m_formatInteger) ? ("0") : ("0.0"))
2309*35238bceSAndroid Build Coastguard Worker << ");\n";
2310*35238bceSAndroid Build Coastguard Worker }
2311*35238bceSAndroid Build Coastguard Worker else if (m_storage == STORAGE_IMAGE)
2312*35238bceSAndroid Build Coastguard Worker {
2313*35238bceSAndroid Build Coastguard Worker for (int readNdx = 0; readNdx < m_perInvocationSize; ++readNdx)
2314*35238bceSAndroid Build Coastguard Worker buf << " allOk = allOk && (" << ((m_useAtomic) ? ("imageAtomicExchange") : ("imageLoad"))
2315*35238bceSAndroid Build Coastguard Worker << "(u_imageIn, ivec2(gl_GlobalInvocationID.x, gl_GlobalInvocationID.y + "
2316*35238bceSAndroid Build Coastguard Worker << (readNdx * m_invocationGridSize) << "u)" << ((m_useAtomic) ? (", anything)") : (").x"))
2317*35238bceSAndroid Build Coastguard Worker << " == " << ((m_formatInteger) ? ("0") : ("0.0")) << ");\n";
2318*35238bceSAndroid Build Coastguard Worker }
2319*35238bceSAndroid Build Coastguard Worker else
2320*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
2321*35238bceSAndroid Build Coastguard Worker
2322*35238bceSAndroid Build Coastguard Worker buf << " sb_result.resultOk[groupNdx] = (allOk) ? (1) : (0);\n"
2323*35238bceSAndroid Build Coastguard Worker << "}\n";
2324*35238bceSAndroid Build Coastguard Worker
2325*35238bceSAndroid Build Coastguard Worker return new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources() << glu::ComputeSource(
2326*35238bceSAndroid Build Coastguard Worker specializeShader(m_context, buf.str().c_str())));
2327*35238bceSAndroid Build Coastguard Worker }
2328*35238bceSAndroid Build Coastguard Worker
2329*35238bceSAndroid Build Coastguard Worker class SSBOConcurrentAtomicCase : public TestCase
2330*35238bceSAndroid Build Coastguard Worker {
2331*35238bceSAndroid Build Coastguard Worker public:
2332*35238bceSAndroid Build Coastguard Worker SSBOConcurrentAtomicCase(Context &context, const char *name, const char *description, int numCalls, int workSize);
2333*35238bceSAndroid Build Coastguard Worker ~SSBOConcurrentAtomicCase(void);
2334*35238bceSAndroid Build Coastguard Worker
2335*35238bceSAndroid Build Coastguard Worker void init(void);
2336*35238bceSAndroid Build Coastguard Worker void deinit(void);
2337*35238bceSAndroid Build Coastguard Worker IterateResult iterate(void);
2338*35238bceSAndroid Build Coastguard Worker
2339*35238bceSAndroid Build Coastguard Worker private:
2340*35238bceSAndroid Build Coastguard Worker std::string genComputeSource(void) const;
2341*35238bceSAndroid Build Coastguard Worker
2342*35238bceSAndroid Build Coastguard Worker const int m_numCalls;
2343*35238bceSAndroid Build Coastguard Worker const int m_workSize;
2344*35238bceSAndroid Build Coastguard Worker glu::ShaderProgram *m_program;
2345*35238bceSAndroid Build Coastguard Worker uint32_t m_bufferID;
2346*35238bceSAndroid Build Coastguard Worker std::vector<uint32_t> m_intermediateResultBuffers;
2347*35238bceSAndroid Build Coastguard Worker };
2348*35238bceSAndroid Build Coastguard Worker
SSBOConcurrentAtomicCase(Context & context,const char * name,const char * description,int numCalls,int workSize)2349*35238bceSAndroid Build Coastguard Worker SSBOConcurrentAtomicCase::SSBOConcurrentAtomicCase(Context &context, const char *name, const char *description,
2350*35238bceSAndroid Build Coastguard Worker int numCalls, int workSize)
2351*35238bceSAndroid Build Coastguard Worker : TestCase(context, name, description)
2352*35238bceSAndroid Build Coastguard Worker , m_numCalls(numCalls)
2353*35238bceSAndroid Build Coastguard Worker , m_workSize(workSize)
2354*35238bceSAndroid Build Coastguard Worker , m_program(DE_NULL)
2355*35238bceSAndroid Build Coastguard Worker , m_bufferID(DE_NULL)
2356*35238bceSAndroid Build Coastguard Worker {
2357*35238bceSAndroid Build Coastguard Worker }
2358*35238bceSAndroid Build Coastguard Worker
~SSBOConcurrentAtomicCase(void)2359*35238bceSAndroid Build Coastguard Worker SSBOConcurrentAtomicCase::~SSBOConcurrentAtomicCase(void)
2360*35238bceSAndroid Build Coastguard Worker {
2361*35238bceSAndroid Build Coastguard Worker deinit();
2362*35238bceSAndroid Build Coastguard Worker }
2363*35238bceSAndroid Build Coastguard Worker
init(void)2364*35238bceSAndroid Build Coastguard Worker void SSBOConcurrentAtomicCase::init(void)
2365*35238bceSAndroid Build Coastguard Worker {
2366*35238bceSAndroid Build Coastguard Worker const glw::Functions &gl = m_context.getRenderContext().getFunctions();
2367*35238bceSAndroid Build Coastguard Worker std::vector<uint32_t> zeroData(m_workSize, 0);
2368*35238bceSAndroid Build Coastguard Worker
2369*35238bceSAndroid Build Coastguard Worker // gen buffers
2370*35238bceSAndroid Build Coastguard Worker
2371*35238bceSAndroid Build Coastguard Worker gl.genBuffers(1, &m_bufferID);
2372*35238bceSAndroid Build Coastguard Worker gl.bindBuffer(GL_SHADER_STORAGE_BUFFER, m_bufferID);
2373*35238bceSAndroid Build Coastguard Worker gl.bufferData(GL_SHADER_STORAGE_BUFFER, sizeof(uint32_t) * m_workSize, &zeroData[0], GL_DYNAMIC_COPY);
2374*35238bceSAndroid Build Coastguard Worker
2375*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < m_numCalls; ++ndx)
2376*35238bceSAndroid Build Coastguard Worker {
2377*35238bceSAndroid Build Coastguard Worker uint32_t buffer = 0;
2378*35238bceSAndroid Build Coastguard Worker
2379*35238bceSAndroid Build Coastguard Worker gl.genBuffers(1, &buffer);
2380*35238bceSAndroid Build Coastguard Worker gl.bindBuffer(GL_SHADER_STORAGE_BUFFER, buffer);
2381*35238bceSAndroid Build Coastguard Worker gl.bufferData(GL_SHADER_STORAGE_BUFFER, sizeof(uint32_t) * m_workSize, &zeroData[0], GL_DYNAMIC_COPY);
2382*35238bceSAndroid Build Coastguard Worker
2383*35238bceSAndroid Build Coastguard Worker m_intermediateResultBuffers.push_back(buffer);
2384*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "gen buffers");
2385*35238bceSAndroid Build Coastguard Worker }
2386*35238bceSAndroid Build Coastguard Worker
2387*35238bceSAndroid Build Coastguard Worker // gen program
2388*35238bceSAndroid Build Coastguard Worker
2389*35238bceSAndroid Build Coastguard Worker m_program = new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources()
2390*35238bceSAndroid Build Coastguard Worker << glu::ComputeSource(genComputeSource()));
2391*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << *m_program;
2392*35238bceSAndroid Build Coastguard Worker if (!m_program->isOk())
2393*35238bceSAndroid Build Coastguard Worker throw tcu::TestError("could not build program");
2394*35238bceSAndroid Build Coastguard Worker }
2395*35238bceSAndroid Build Coastguard Worker
deinit(void)2396*35238bceSAndroid Build Coastguard Worker void SSBOConcurrentAtomicCase::deinit(void)
2397*35238bceSAndroid Build Coastguard Worker {
2398*35238bceSAndroid Build Coastguard Worker if (m_bufferID)
2399*35238bceSAndroid Build Coastguard Worker {
2400*35238bceSAndroid Build Coastguard Worker m_context.getRenderContext().getFunctions().deleteBuffers(1, &m_bufferID);
2401*35238bceSAndroid Build Coastguard Worker m_bufferID = 0;
2402*35238bceSAndroid Build Coastguard Worker }
2403*35238bceSAndroid Build Coastguard Worker
2404*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < (int)m_intermediateResultBuffers.size(); ++ndx)
2405*35238bceSAndroid Build Coastguard Worker m_context.getRenderContext().getFunctions().deleteBuffers(1, &m_intermediateResultBuffers[ndx]);
2406*35238bceSAndroid Build Coastguard Worker m_intermediateResultBuffers.clear();
2407*35238bceSAndroid Build Coastguard Worker
2408*35238bceSAndroid Build Coastguard Worker delete m_program;
2409*35238bceSAndroid Build Coastguard Worker m_program = DE_NULL;
2410*35238bceSAndroid Build Coastguard Worker }
2411*35238bceSAndroid Build Coastguard Worker
iterate(void)2412*35238bceSAndroid Build Coastguard Worker TestCase::IterateResult SSBOConcurrentAtomicCase::iterate(void)
2413*35238bceSAndroid Build Coastguard Worker {
2414*35238bceSAndroid Build Coastguard Worker const glw::Functions &gl = m_context.getRenderContext().getFunctions();
2415*35238bceSAndroid Build Coastguard Worker const uint32_t sumValue = (uint32_t)(m_numCalls * (m_numCalls + 1) / 2);
2416*35238bceSAndroid Build Coastguard Worker std::vector<int> deltas;
2417*35238bceSAndroid Build Coastguard Worker
2418*35238bceSAndroid Build Coastguard Worker // generate unique deltas
2419*35238bceSAndroid Build Coastguard Worker generateShuffledRamp(m_numCalls, deltas);
2420*35238bceSAndroid Build Coastguard Worker
2421*35238bceSAndroid Build Coastguard Worker // invoke program N times, each with a different delta
2422*35238bceSAndroid Build Coastguard Worker {
2423*35238bceSAndroid Build Coastguard Worker const int deltaLocation = gl.getUniformLocation(m_program->getProgram(), "u_atomicDelta");
2424*35238bceSAndroid Build Coastguard Worker
2425*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Running shader " << m_numCalls << " times.\n"
2426*35238bceSAndroid Build Coastguard Worker << "Num groups = (" << m_workSize << ", 1, 1)\n"
2427*35238bceSAndroid Build Coastguard Worker << "Setting u_atomicDelta to a unique value for each call.\n"
2428*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
2429*35238bceSAndroid Build Coastguard Worker
2430*35238bceSAndroid Build Coastguard Worker if (deltaLocation == -1)
2431*35238bceSAndroid Build Coastguard Worker throw tcu::TestError("u_atomicDelta location was -1");
2432*35238bceSAndroid Build Coastguard Worker
2433*35238bceSAndroid Build Coastguard Worker gl.useProgram(m_program->getProgram());
2434*35238bceSAndroid Build Coastguard Worker gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, m_bufferID);
2435*35238bceSAndroid Build Coastguard Worker
2436*35238bceSAndroid Build Coastguard Worker for (int callNdx = 0; callNdx < m_numCalls; ++callNdx)
2437*35238bceSAndroid Build Coastguard Worker {
2438*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Call " << callNdx << ": u_atomicDelta = " << deltas[callNdx]
2439*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
2440*35238bceSAndroid Build Coastguard Worker
2441*35238bceSAndroid Build Coastguard Worker gl.uniform1ui(deltaLocation, deltas[callNdx]);
2442*35238bceSAndroid Build Coastguard Worker gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_intermediateResultBuffers[callNdx]);
2443*35238bceSAndroid Build Coastguard Worker gl.dispatchCompute(m_workSize, 1, 1);
2444*35238bceSAndroid Build Coastguard Worker }
2445*35238bceSAndroid Build Coastguard Worker
2446*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "post dispatch");
2447*35238bceSAndroid Build Coastguard Worker }
2448*35238bceSAndroid Build Coastguard Worker
2449*35238bceSAndroid Build Coastguard Worker // Verify result
2450*35238bceSAndroid Build Coastguard Worker {
2451*35238bceSAndroid Build Coastguard Worker std::vector<uint32_t> result;
2452*35238bceSAndroid Build Coastguard Worker
2453*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Verifying work buffer, it should be filled with value "
2454*35238bceSAndroid Build Coastguard Worker << sumValue << tcu::TestLog::EndMessage;
2455*35238bceSAndroid Build Coastguard Worker
2456*35238bceSAndroid Build Coastguard Worker gl.bindBuffer(GL_SHADER_STORAGE_BUFFER, m_bufferID);
2457*35238bceSAndroid Build Coastguard Worker readBuffer(gl, GL_SHADER_STORAGE_BUFFER, m_workSize, result);
2458*35238bceSAndroid Build Coastguard Worker
2459*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < m_workSize; ++ndx)
2460*35238bceSAndroid Build Coastguard Worker {
2461*35238bceSAndroid Build Coastguard Worker if (result[ndx] != sumValue)
2462*35238bceSAndroid Build Coastguard Worker {
2463*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Work buffer error, at index " << ndx
2464*35238bceSAndroid Build Coastguard Worker << " expected value " << (sumValue) << ", got " << result[ndx] << "\n"
2465*35238bceSAndroid Build Coastguard Worker << "Work buffer contains invalid values." << tcu::TestLog::EndMessage;
2466*35238bceSAndroid Build Coastguard Worker
2467*35238bceSAndroid Build Coastguard Worker m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Buffer contents invalid");
2468*35238bceSAndroid Build Coastguard Worker return STOP;
2469*35238bceSAndroid Build Coastguard Worker }
2470*35238bceSAndroid Build Coastguard Worker }
2471*35238bceSAndroid Build Coastguard Worker
2472*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Work buffer contents are valid." << tcu::TestLog::EndMessage;
2473*35238bceSAndroid Build Coastguard Worker }
2474*35238bceSAndroid Build Coastguard Worker
2475*35238bceSAndroid Build Coastguard Worker // verify steps
2476*35238bceSAndroid Build Coastguard Worker {
2477*35238bceSAndroid Build Coastguard Worker std::vector<std::vector<uint32_t>> intermediateResults(m_numCalls);
2478*35238bceSAndroid Build Coastguard Worker std::vector<uint32_t> valueChain(m_numCalls);
2479*35238bceSAndroid Build Coastguard Worker
2480*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Verifying intermediate results. " << tcu::TestLog::EndMessage;
2481*35238bceSAndroid Build Coastguard Worker
2482*35238bceSAndroid Build Coastguard Worker // collect results
2483*35238bceSAndroid Build Coastguard Worker
2484*35238bceSAndroid Build Coastguard Worker for (int callNdx = 0; callNdx < m_numCalls; ++callNdx)
2485*35238bceSAndroid Build Coastguard Worker {
2486*35238bceSAndroid Build Coastguard Worker gl.bindBuffer(GL_SHADER_STORAGE_BUFFER, m_intermediateResultBuffers[callNdx]);
2487*35238bceSAndroid Build Coastguard Worker readBuffer(gl, GL_SHADER_STORAGE_BUFFER, m_workSize, intermediateResults[callNdx]);
2488*35238bceSAndroid Build Coastguard Worker }
2489*35238bceSAndroid Build Coastguard Worker
2490*35238bceSAndroid Build Coastguard Worker // verify values
2491*35238bceSAndroid Build Coastguard Worker
2492*35238bceSAndroid Build Coastguard Worker for (int valueNdx = 0; valueNdx < m_workSize; ++valueNdx)
2493*35238bceSAndroid Build Coastguard Worker {
2494*35238bceSAndroid Build Coastguard Worker int invalidOperationNdx;
2495*35238bceSAndroid Build Coastguard Worker uint32_t errorDelta;
2496*35238bceSAndroid Build Coastguard Worker uint32_t errorExpected;
2497*35238bceSAndroid Build Coastguard Worker
2498*35238bceSAndroid Build Coastguard Worker // collect result chain for each element
2499*35238bceSAndroid Build Coastguard Worker for (int callNdx = 0; callNdx < m_numCalls; ++callNdx)
2500*35238bceSAndroid Build Coastguard Worker valueChain[callNdx] = intermediateResults[callNdx][valueNdx];
2501*35238bceSAndroid Build Coastguard Worker
2502*35238bceSAndroid Build Coastguard Worker // check there exists a path from 0 to sumValue using each addition once
2503*35238bceSAndroid Build Coastguard Worker // decompose cumulative results to addition operations (all additions positive => this works)
2504*35238bceSAndroid Build Coastguard Worker
2505*35238bceSAndroid Build Coastguard Worker std::sort(valueChain.begin(), valueChain.end());
2506*35238bceSAndroid Build Coastguard Worker
2507*35238bceSAndroid Build Coastguard Worker // validate chain
2508*35238bceSAndroid Build Coastguard Worker if (!validateSortedAtomicRampAdditionValueChain(valueChain, sumValue, invalidOperationNdx, errorDelta,
2509*35238bceSAndroid Build Coastguard Worker errorExpected))
2510*35238bceSAndroid Build Coastguard Worker {
2511*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Intermediate buffer error, at value index " << valueNdx
2512*35238bceSAndroid Build Coastguard Worker << ", applied operation index " << invalidOperationNdx << ", value was increased by "
2513*35238bceSAndroid Build Coastguard Worker << errorDelta << ", but expected " << errorExpected << ".\n"
2514*35238bceSAndroid Build Coastguard Worker << "Intermediate buffer contains invalid values. Values at index " << valueNdx
2515*35238bceSAndroid Build Coastguard Worker << "\n"
2516*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
2517*35238bceSAndroid Build Coastguard Worker
2518*35238bceSAndroid Build Coastguard Worker for (int logCallNdx = 0; logCallNdx < m_numCalls; ++logCallNdx)
2519*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Value[" << logCallNdx
2520*35238bceSAndroid Build Coastguard Worker << "] = " << intermediateResults[logCallNdx][valueNdx]
2521*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
2522*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Result = " << sumValue << tcu::TestLog::EndMessage;
2523*35238bceSAndroid Build Coastguard Worker
2524*35238bceSAndroid Build Coastguard Worker m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Buffer contents invalid");
2525*35238bceSAndroid Build Coastguard Worker return STOP;
2526*35238bceSAndroid Build Coastguard Worker }
2527*35238bceSAndroid Build Coastguard Worker }
2528*35238bceSAndroid Build Coastguard Worker
2529*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Intermediate buffers are valid." << tcu::TestLog::EndMessage;
2530*35238bceSAndroid Build Coastguard Worker }
2531*35238bceSAndroid Build Coastguard Worker
2532*35238bceSAndroid Build Coastguard Worker m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2533*35238bceSAndroid Build Coastguard Worker return STOP;
2534*35238bceSAndroid Build Coastguard Worker }
2535*35238bceSAndroid Build Coastguard Worker
genComputeSource(void) const2536*35238bceSAndroid Build Coastguard Worker std::string SSBOConcurrentAtomicCase::genComputeSource(void) const
2537*35238bceSAndroid Build Coastguard Worker {
2538*35238bceSAndroid Build Coastguard Worker std::ostringstream buf;
2539*35238bceSAndroid Build Coastguard Worker
2540*35238bceSAndroid Build Coastguard Worker buf << "${GLSL_VERSION_DECL}\n"
2541*35238bceSAndroid Build Coastguard Worker << "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
2542*35238bceSAndroid Build Coastguard Worker << "layout (binding = 1, std430) writeonly buffer IntermediateResults\n"
2543*35238bceSAndroid Build Coastguard Worker << "{\n"
2544*35238bceSAndroid Build Coastguard Worker << " highp uint values[" << m_workSize << "];\n"
2545*35238bceSAndroid Build Coastguard Worker << "} sb_ires;\n"
2546*35238bceSAndroid Build Coastguard Worker << "\n"
2547*35238bceSAndroid Build Coastguard Worker << "layout (binding = 2, std430) volatile buffer WorkBuffer\n"
2548*35238bceSAndroid Build Coastguard Worker << "{\n"
2549*35238bceSAndroid Build Coastguard Worker << " highp uint values[" << m_workSize << "];\n"
2550*35238bceSAndroid Build Coastguard Worker << "} sb_work;\n"
2551*35238bceSAndroid Build Coastguard Worker << "uniform highp uint u_atomicDelta;\n"
2552*35238bceSAndroid Build Coastguard Worker << "\n"
2553*35238bceSAndroid Build Coastguard Worker << "void main ()\n"
2554*35238bceSAndroid Build Coastguard Worker << "{\n"
2555*35238bceSAndroid Build Coastguard Worker << " highp uint invocationIndex = gl_GlobalInvocationID.x;\n"
2556*35238bceSAndroid Build Coastguard Worker << " sb_ires.values[invocationIndex] = atomicAdd(sb_work.values[invocationIndex], u_atomicDelta);\n"
2557*35238bceSAndroid Build Coastguard Worker << "}";
2558*35238bceSAndroid Build Coastguard Worker
2559*35238bceSAndroid Build Coastguard Worker return specializeShader(m_context, buf.str().c_str());
2560*35238bceSAndroid Build Coastguard Worker }
2561*35238bceSAndroid Build Coastguard Worker
2562*35238bceSAndroid Build Coastguard Worker class ConcurrentAtomicCounterCase : public TestCase
2563*35238bceSAndroid Build Coastguard Worker {
2564*35238bceSAndroid Build Coastguard Worker public:
2565*35238bceSAndroid Build Coastguard Worker ConcurrentAtomicCounterCase(Context &context, const char *name, const char *description, int numCalls,
2566*35238bceSAndroid Build Coastguard Worker int workSize);
2567*35238bceSAndroid Build Coastguard Worker ~ConcurrentAtomicCounterCase(void);
2568*35238bceSAndroid Build Coastguard Worker
2569*35238bceSAndroid Build Coastguard Worker void init(void);
2570*35238bceSAndroid Build Coastguard Worker void deinit(void);
2571*35238bceSAndroid Build Coastguard Worker IterateResult iterate(void);
2572*35238bceSAndroid Build Coastguard Worker
2573*35238bceSAndroid Build Coastguard Worker private:
2574*35238bceSAndroid Build Coastguard Worker std::string genComputeSource(bool evenOdd) const;
2575*35238bceSAndroid Build Coastguard Worker
2576*35238bceSAndroid Build Coastguard Worker const int m_numCalls;
2577*35238bceSAndroid Build Coastguard Worker const int m_workSize;
2578*35238bceSAndroid Build Coastguard Worker glu::ShaderProgram *m_evenProgram;
2579*35238bceSAndroid Build Coastguard Worker glu::ShaderProgram *m_oddProgram;
2580*35238bceSAndroid Build Coastguard Worker uint32_t m_counterBuffer;
2581*35238bceSAndroid Build Coastguard Worker uint32_t m_intermediateResultBuffer;
2582*35238bceSAndroid Build Coastguard Worker };
2583*35238bceSAndroid Build Coastguard Worker
ConcurrentAtomicCounterCase(Context & context,const char * name,const char * description,int numCalls,int workSize)2584*35238bceSAndroid Build Coastguard Worker ConcurrentAtomicCounterCase::ConcurrentAtomicCounterCase(Context &context, const char *name, const char *description,
2585*35238bceSAndroid Build Coastguard Worker int numCalls, int workSize)
2586*35238bceSAndroid Build Coastguard Worker : TestCase(context, name, description)
2587*35238bceSAndroid Build Coastguard Worker , m_numCalls(numCalls)
2588*35238bceSAndroid Build Coastguard Worker , m_workSize(workSize)
2589*35238bceSAndroid Build Coastguard Worker , m_evenProgram(DE_NULL)
2590*35238bceSAndroid Build Coastguard Worker , m_oddProgram(DE_NULL)
2591*35238bceSAndroid Build Coastguard Worker , m_counterBuffer(DE_NULL)
2592*35238bceSAndroid Build Coastguard Worker , m_intermediateResultBuffer(DE_NULL)
2593*35238bceSAndroid Build Coastguard Worker {
2594*35238bceSAndroid Build Coastguard Worker }
2595*35238bceSAndroid Build Coastguard Worker
~ConcurrentAtomicCounterCase(void)2596*35238bceSAndroid Build Coastguard Worker ConcurrentAtomicCounterCase::~ConcurrentAtomicCounterCase(void)
2597*35238bceSAndroid Build Coastguard Worker {
2598*35238bceSAndroid Build Coastguard Worker deinit();
2599*35238bceSAndroid Build Coastguard Worker }
2600*35238bceSAndroid Build Coastguard Worker
init(void)2601*35238bceSAndroid Build Coastguard Worker void ConcurrentAtomicCounterCase::init(void)
2602*35238bceSAndroid Build Coastguard Worker {
2603*35238bceSAndroid Build Coastguard Worker const glw::Functions &gl = m_context.getRenderContext().getFunctions();
2604*35238bceSAndroid Build Coastguard Worker const std::vector<uint32_t> zeroData(m_numCalls * m_workSize, 0);
2605*35238bceSAndroid Build Coastguard Worker
2606*35238bceSAndroid Build Coastguard Worker // gen buffer
2607*35238bceSAndroid Build Coastguard Worker
2608*35238bceSAndroid Build Coastguard Worker gl.genBuffers(1, &m_counterBuffer);
2609*35238bceSAndroid Build Coastguard Worker gl.bindBuffer(GL_SHADER_STORAGE_BUFFER, m_counterBuffer);
2610*35238bceSAndroid Build Coastguard Worker gl.bufferData(GL_SHADER_STORAGE_BUFFER, sizeof(uint32_t), &zeroData[0], GL_DYNAMIC_COPY);
2611*35238bceSAndroid Build Coastguard Worker
2612*35238bceSAndroid Build Coastguard Worker gl.genBuffers(1, &m_intermediateResultBuffer);
2613*35238bceSAndroid Build Coastguard Worker gl.bindBuffer(GL_SHADER_STORAGE_BUFFER, m_intermediateResultBuffer);
2614*35238bceSAndroid Build Coastguard Worker gl.bufferData(GL_SHADER_STORAGE_BUFFER, sizeof(uint32_t) * m_numCalls * m_workSize, &zeroData[0], GL_DYNAMIC_COPY);
2615*35238bceSAndroid Build Coastguard Worker
2616*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "gen buffers");
2617*35238bceSAndroid Build Coastguard Worker
2618*35238bceSAndroid Build Coastguard Worker // gen programs
2619*35238bceSAndroid Build Coastguard Worker
2620*35238bceSAndroid Build Coastguard Worker {
2621*35238bceSAndroid Build Coastguard Worker const tcu::ScopedLogSection section(m_testCtx.getLog(), "EvenProgram", "Even program");
2622*35238bceSAndroid Build Coastguard Worker
2623*35238bceSAndroid Build Coastguard Worker m_evenProgram = new glu::ShaderProgram(m_context.getRenderContext(),
2624*35238bceSAndroid Build Coastguard Worker glu::ProgramSources() << glu::ComputeSource(genComputeSource(true)));
2625*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << *m_evenProgram;
2626*35238bceSAndroid Build Coastguard Worker if (!m_evenProgram->isOk())
2627*35238bceSAndroid Build Coastguard Worker throw tcu::TestError("could not build program");
2628*35238bceSAndroid Build Coastguard Worker }
2629*35238bceSAndroid Build Coastguard Worker {
2630*35238bceSAndroid Build Coastguard Worker const tcu::ScopedLogSection section(m_testCtx.getLog(), "OddProgram", "Odd program");
2631*35238bceSAndroid Build Coastguard Worker
2632*35238bceSAndroid Build Coastguard Worker m_oddProgram = new glu::ShaderProgram(m_context.getRenderContext(),
2633*35238bceSAndroid Build Coastguard Worker glu::ProgramSources() << glu::ComputeSource(genComputeSource(false)));
2634*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << *m_oddProgram;
2635*35238bceSAndroid Build Coastguard Worker if (!m_oddProgram->isOk())
2636*35238bceSAndroid Build Coastguard Worker throw tcu::TestError("could not build program");
2637*35238bceSAndroid Build Coastguard Worker }
2638*35238bceSAndroid Build Coastguard Worker }
2639*35238bceSAndroid Build Coastguard Worker
deinit(void)2640*35238bceSAndroid Build Coastguard Worker void ConcurrentAtomicCounterCase::deinit(void)
2641*35238bceSAndroid Build Coastguard Worker {
2642*35238bceSAndroid Build Coastguard Worker if (m_counterBuffer)
2643*35238bceSAndroid Build Coastguard Worker {
2644*35238bceSAndroid Build Coastguard Worker m_context.getRenderContext().getFunctions().deleteBuffers(1, &m_counterBuffer);
2645*35238bceSAndroid Build Coastguard Worker m_counterBuffer = 0;
2646*35238bceSAndroid Build Coastguard Worker }
2647*35238bceSAndroid Build Coastguard Worker if (m_intermediateResultBuffer)
2648*35238bceSAndroid Build Coastguard Worker {
2649*35238bceSAndroid Build Coastguard Worker m_context.getRenderContext().getFunctions().deleteBuffers(1, &m_intermediateResultBuffer);
2650*35238bceSAndroid Build Coastguard Worker m_intermediateResultBuffer = 0;
2651*35238bceSAndroid Build Coastguard Worker }
2652*35238bceSAndroid Build Coastguard Worker
2653*35238bceSAndroid Build Coastguard Worker delete m_evenProgram;
2654*35238bceSAndroid Build Coastguard Worker m_evenProgram = DE_NULL;
2655*35238bceSAndroid Build Coastguard Worker
2656*35238bceSAndroid Build Coastguard Worker delete m_oddProgram;
2657*35238bceSAndroid Build Coastguard Worker m_oddProgram = DE_NULL;
2658*35238bceSAndroid Build Coastguard Worker }
2659*35238bceSAndroid Build Coastguard Worker
iterate(void)2660*35238bceSAndroid Build Coastguard Worker TestCase::IterateResult ConcurrentAtomicCounterCase::iterate(void)
2661*35238bceSAndroid Build Coastguard Worker {
2662*35238bceSAndroid Build Coastguard Worker const glw::Functions &gl = m_context.getRenderContext().getFunctions();
2663*35238bceSAndroid Build Coastguard Worker
2664*35238bceSAndroid Build Coastguard Worker // invoke program N times, each with a different delta
2665*35238bceSAndroid Build Coastguard Worker {
2666*35238bceSAndroid Build Coastguard Worker const int evenCallNdxLocation = gl.getUniformLocation(m_evenProgram->getProgram(), "u_callNdx");
2667*35238bceSAndroid Build Coastguard Worker const int oddCallNdxLocation = gl.getUniformLocation(m_oddProgram->getProgram(), "u_callNdx");
2668*35238bceSAndroid Build Coastguard Worker
2669*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Running shader pair (even & odd) " << m_numCalls << " times.\n"
2670*35238bceSAndroid Build Coastguard Worker << "Num groups = (" << m_workSize << ", 1, 1)\n"
2671*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
2672*35238bceSAndroid Build Coastguard Worker
2673*35238bceSAndroid Build Coastguard Worker if (evenCallNdxLocation == -1)
2674*35238bceSAndroid Build Coastguard Worker throw tcu::TestError("u_callNdx location was -1");
2675*35238bceSAndroid Build Coastguard Worker if (oddCallNdxLocation == -1)
2676*35238bceSAndroid Build Coastguard Worker throw tcu::TestError("u_callNdx location was -1");
2677*35238bceSAndroid Build Coastguard Worker
2678*35238bceSAndroid Build Coastguard Worker gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_intermediateResultBuffer);
2679*35238bceSAndroid Build Coastguard Worker gl.bindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0, m_counterBuffer);
2680*35238bceSAndroid Build Coastguard Worker
2681*35238bceSAndroid Build Coastguard Worker for (int callNdx = 0; callNdx < m_numCalls; ++callNdx)
2682*35238bceSAndroid Build Coastguard Worker {
2683*35238bceSAndroid Build Coastguard Worker gl.useProgram(m_evenProgram->getProgram());
2684*35238bceSAndroid Build Coastguard Worker gl.uniform1ui(evenCallNdxLocation, (uint32_t)callNdx);
2685*35238bceSAndroid Build Coastguard Worker gl.dispatchCompute(m_workSize, 1, 1);
2686*35238bceSAndroid Build Coastguard Worker
2687*35238bceSAndroid Build Coastguard Worker gl.useProgram(m_oddProgram->getProgram());
2688*35238bceSAndroid Build Coastguard Worker gl.uniform1ui(oddCallNdxLocation, (uint32_t)callNdx);
2689*35238bceSAndroid Build Coastguard Worker gl.dispatchCompute(m_workSize, 1, 1);
2690*35238bceSAndroid Build Coastguard Worker }
2691*35238bceSAndroid Build Coastguard Worker
2692*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "post dispatch");
2693*35238bceSAndroid Build Coastguard Worker }
2694*35238bceSAndroid Build Coastguard Worker
2695*35238bceSAndroid Build Coastguard Worker // Verify result
2696*35238bceSAndroid Build Coastguard Worker {
2697*35238bceSAndroid Build Coastguard Worker uint32_t result;
2698*35238bceSAndroid Build Coastguard Worker
2699*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Verifying work buffer, it should be " << m_numCalls * m_workSize
2700*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
2701*35238bceSAndroid Build Coastguard Worker
2702*35238bceSAndroid Build Coastguard Worker gl.bindBuffer(GL_ATOMIC_COUNTER_BUFFER, m_counterBuffer);
2703*35238bceSAndroid Build Coastguard Worker result = readBufferUint32(gl, GL_ATOMIC_COUNTER_BUFFER);
2704*35238bceSAndroid Build Coastguard Worker
2705*35238bceSAndroid Build Coastguard Worker if ((int)result != m_numCalls * m_workSize)
2706*35238bceSAndroid Build Coastguard Worker {
2707*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Counter buffer error, expected value "
2708*35238bceSAndroid Build Coastguard Worker << (m_numCalls * m_workSize) << ", got " << result << "\n"
2709*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
2710*35238bceSAndroid Build Coastguard Worker
2711*35238bceSAndroid Build Coastguard Worker m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Buffer contents invalid");
2712*35238bceSAndroid Build Coastguard Worker return STOP;
2713*35238bceSAndroid Build Coastguard Worker }
2714*35238bceSAndroid Build Coastguard Worker
2715*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Counter buffer is valid." << tcu::TestLog::EndMessage;
2716*35238bceSAndroid Build Coastguard Worker }
2717*35238bceSAndroid Build Coastguard Worker
2718*35238bceSAndroid Build Coastguard Worker // verify steps
2719*35238bceSAndroid Build Coastguard Worker {
2720*35238bceSAndroid Build Coastguard Worker std::vector<uint32_t> intermediateResults;
2721*35238bceSAndroid Build Coastguard Worker
2722*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Verifying intermediate results. " << tcu::TestLog::EndMessage;
2723*35238bceSAndroid Build Coastguard Worker
2724*35238bceSAndroid Build Coastguard Worker // collect results
2725*35238bceSAndroid Build Coastguard Worker
2726*35238bceSAndroid Build Coastguard Worker gl.bindBuffer(GL_SHADER_STORAGE_BUFFER, m_intermediateResultBuffer);
2727*35238bceSAndroid Build Coastguard Worker readBuffer(gl, GL_SHADER_STORAGE_BUFFER, m_numCalls * m_workSize, intermediateResults);
2728*35238bceSAndroid Build Coastguard Worker
2729*35238bceSAndroid Build Coastguard Worker // verify values
2730*35238bceSAndroid Build Coastguard Worker
2731*35238bceSAndroid Build Coastguard Worker std::sort(intermediateResults.begin(), intermediateResults.end());
2732*35238bceSAndroid Build Coastguard Worker
2733*35238bceSAndroid Build Coastguard Worker for (int valueNdx = 0; valueNdx < m_workSize * m_numCalls; ++valueNdx)
2734*35238bceSAndroid Build Coastguard Worker {
2735*35238bceSAndroid Build Coastguard Worker if ((int)intermediateResults[valueNdx] != valueNdx)
2736*35238bceSAndroid Build Coastguard Worker {
2737*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Intermediate buffer error, at value index " << valueNdx
2738*35238bceSAndroid Build Coastguard Worker << ", expected " << valueNdx << ", got " << intermediateResults[valueNdx] << ".\n"
2739*35238bceSAndroid Build Coastguard Worker << "Intermediate buffer contains invalid values. Intermediate results:\n"
2740*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
2741*35238bceSAndroid Build Coastguard Worker
2742*35238bceSAndroid Build Coastguard Worker for (int logCallNdx = 0; logCallNdx < m_workSize * m_numCalls; ++logCallNdx)
2743*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Value[" << logCallNdx
2744*35238bceSAndroid Build Coastguard Worker << "] = " << intermediateResults[logCallNdx] << tcu::TestLog::EndMessage;
2745*35238bceSAndroid Build Coastguard Worker
2746*35238bceSAndroid Build Coastguard Worker m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Buffer contents invalid");
2747*35238bceSAndroid Build Coastguard Worker return STOP;
2748*35238bceSAndroid Build Coastguard Worker }
2749*35238bceSAndroid Build Coastguard Worker }
2750*35238bceSAndroid Build Coastguard Worker
2751*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Intermediate buffers are valid." << tcu::TestLog::EndMessage;
2752*35238bceSAndroid Build Coastguard Worker }
2753*35238bceSAndroid Build Coastguard Worker
2754*35238bceSAndroid Build Coastguard Worker m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2755*35238bceSAndroid Build Coastguard Worker return STOP;
2756*35238bceSAndroid Build Coastguard Worker }
2757*35238bceSAndroid Build Coastguard Worker
genComputeSource(bool evenOdd) const2758*35238bceSAndroid Build Coastguard Worker std::string ConcurrentAtomicCounterCase::genComputeSource(bool evenOdd) const
2759*35238bceSAndroid Build Coastguard Worker {
2760*35238bceSAndroid Build Coastguard Worker std::ostringstream buf;
2761*35238bceSAndroid Build Coastguard Worker
2762*35238bceSAndroid Build Coastguard Worker buf << "${GLSL_VERSION_DECL}\n"
2763*35238bceSAndroid Build Coastguard Worker << "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
2764*35238bceSAndroid Build Coastguard Worker << "layout (binding = 1, std430) writeonly buffer IntermediateResults\n"
2765*35238bceSAndroid Build Coastguard Worker << "{\n"
2766*35238bceSAndroid Build Coastguard Worker << " highp uint values[" << m_workSize * m_numCalls << "];\n"
2767*35238bceSAndroid Build Coastguard Worker << "} sb_ires;\n"
2768*35238bceSAndroid Build Coastguard Worker << "\n"
2769*35238bceSAndroid Build Coastguard Worker << "layout (binding = 0, offset = 0) uniform atomic_uint u_counter;\n"
2770*35238bceSAndroid Build Coastguard Worker << "uniform highp uint u_callNdx;\n"
2771*35238bceSAndroid Build Coastguard Worker << "\n"
2772*35238bceSAndroid Build Coastguard Worker << "void main ()\n"
2773*35238bceSAndroid Build Coastguard Worker << "{\n"
2774*35238bceSAndroid Build Coastguard Worker << " highp uint dataNdx = u_callNdx * " << m_workSize << "u + gl_GlobalInvocationID.x;\n"
2775*35238bceSAndroid Build Coastguard Worker << " if ((dataNdx % 2u) == " << ((evenOdd) ? (0) : (1)) << "u)\n"
2776*35238bceSAndroid Build Coastguard Worker << " sb_ires.values[dataNdx] = atomicCounterIncrement(u_counter);\n"
2777*35238bceSAndroid Build Coastguard Worker << "}";
2778*35238bceSAndroid Build Coastguard Worker
2779*35238bceSAndroid Build Coastguard Worker return specializeShader(m_context, buf.str().c_str());
2780*35238bceSAndroid Build Coastguard Worker }
2781*35238bceSAndroid Build Coastguard Worker
2782*35238bceSAndroid Build Coastguard Worker class ConcurrentImageAtomicCase : public TestCase
2783*35238bceSAndroid Build Coastguard Worker {
2784*35238bceSAndroid Build Coastguard Worker public:
2785*35238bceSAndroid Build Coastguard Worker ConcurrentImageAtomicCase(Context &context, const char *name, const char *description, int numCalls, int workSize);
2786*35238bceSAndroid Build Coastguard Worker ~ConcurrentImageAtomicCase(void);
2787*35238bceSAndroid Build Coastguard Worker
2788*35238bceSAndroid Build Coastguard Worker void init(void);
2789*35238bceSAndroid Build Coastguard Worker void deinit(void);
2790*35238bceSAndroid Build Coastguard Worker IterateResult iterate(void);
2791*35238bceSAndroid Build Coastguard Worker
2792*35238bceSAndroid Build Coastguard Worker private:
2793*35238bceSAndroid Build Coastguard Worker void readWorkImage(std::vector<uint32_t> &result);
2794*35238bceSAndroid Build Coastguard Worker
2795*35238bceSAndroid Build Coastguard Worker std::string genComputeSource(void) const;
2796*35238bceSAndroid Build Coastguard Worker std::string genImageReadSource(void) const;
2797*35238bceSAndroid Build Coastguard Worker std::string genImageClearSource(void) const;
2798*35238bceSAndroid Build Coastguard Worker
2799*35238bceSAndroid Build Coastguard Worker const int m_numCalls;
2800*35238bceSAndroid Build Coastguard Worker const int m_workSize;
2801*35238bceSAndroid Build Coastguard Worker glu::ShaderProgram *m_program;
2802*35238bceSAndroid Build Coastguard Worker glu::ShaderProgram *m_imageReadProgram;
2803*35238bceSAndroid Build Coastguard Worker glu::ShaderProgram *m_imageClearProgram;
2804*35238bceSAndroid Build Coastguard Worker uint32_t m_imageID;
2805*35238bceSAndroid Build Coastguard Worker std::vector<uint32_t> m_intermediateResultBuffers;
2806*35238bceSAndroid Build Coastguard Worker };
2807*35238bceSAndroid Build Coastguard Worker
ConcurrentImageAtomicCase(Context & context,const char * name,const char * description,int numCalls,int workSize)2808*35238bceSAndroid Build Coastguard Worker ConcurrentImageAtomicCase::ConcurrentImageAtomicCase(Context &context, const char *name, const char *description,
2809*35238bceSAndroid Build Coastguard Worker int numCalls, int workSize)
2810*35238bceSAndroid Build Coastguard Worker : TestCase(context, name, description)
2811*35238bceSAndroid Build Coastguard Worker , m_numCalls(numCalls)
2812*35238bceSAndroid Build Coastguard Worker , m_workSize(workSize)
2813*35238bceSAndroid Build Coastguard Worker , m_program(DE_NULL)
2814*35238bceSAndroid Build Coastguard Worker , m_imageReadProgram(DE_NULL)
2815*35238bceSAndroid Build Coastguard Worker , m_imageClearProgram(DE_NULL)
2816*35238bceSAndroid Build Coastguard Worker , m_imageID(DE_NULL)
2817*35238bceSAndroid Build Coastguard Worker {
2818*35238bceSAndroid Build Coastguard Worker }
2819*35238bceSAndroid Build Coastguard Worker
~ConcurrentImageAtomicCase(void)2820*35238bceSAndroid Build Coastguard Worker ConcurrentImageAtomicCase::~ConcurrentImageAtomicCase(void)
2821*35238bceSAndroid Build Coastguard Worker {
2822*35238bceSAndroid Build Coastguard Worker deinit();
2823*35238bceSAndroid Build Coastguard Worker }
2824*35238bceSAndroid Build Coastguard Worker
init(void)2825*35238bceSAndroid Build Coastguard Worker void ConcurrentImageAtomicCase::init(void)
2826*35238bceSAndroid Build Coastguard Worker {
2827*35238bceSAndroid Build Coastguard Worker const glw::Functions &gl = m_context.getRenderContext().getFunctions();
2828*35238bceSAndroid Build Coastguard Worker std::vector<uint32_t> zeroData(m_workSize * m_workSize, 0);
2829*35238bceSAndroid Build Coastguard Worker
2830*35238bceSAndroid Build Coastguard Worker if (!checkSupport(m_context))
2831*35238bceSAndroid Build Coastguard Worker throw tcu::NotSupportedError("Test requires GL_OES_shader_image_atomic");
2832*35238bceSAndroid Build Coastguard Worker
2833*35238bceSAndroid Build Coastguard Worker // gen image
2834*35238bceSAndroid Build Coastguard Worker
2835*35238bceSAndroid Build Coastguard Worker gl.genTextures(1, &m_imageID);
2836*35238bceSAndroid Build Coastguard Worker gl.bindTexture(GL_TEXTURE_2D, m_imageID);
2837*35238bceSAndroid Build Coastguard Worker gl.texStorage2D(GL_TEXTURE_2D, 1, GL_R32UI, m_workSize, m_workSize);
2838*35238bceSAndroid Build Coastguard Worker gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2839*35238bceSAndroid Build Coastguard Worker gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2840*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "gen tex");
2841*35238bceSAndroid Build Coastguard Worker
2842*35238bceSAndroid Build Coastguard Worker // gen buffers
2843*35238bceSAndroid Build Coastguard Worker
2844*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < m_numCalls; ++ndx)
2845*35238bceSAndroid Build Coastguard Worker {
2846*35238bceSAndroid Build Coastguard Worker uint32_t buffer = 0;
2847*35238bceSAndroid Build Coastguard Worker
2848*35238bceSAndroid Build Coastguard Worker gl.genBuffers(1, &buffer);
2849*35238bceSAndroid Build Coastguard Worker gl.bindBuffer(GL_SHADER_STORAGE_BUFFER, buffer);
2850*35238bceSAndroid Build Coastguard Worker gl.bufferData(GL_SHADER_STORAGE_BUFFER, sizeof(uint32_t) * m_workSize * m_workSize, &zeroData[0],
2851*35238bceSAndroid Build Coastguard Worker GL_DYNAMIC_COPY);
2852*35238bceSAndroid Build Coastguard Worker
2853*35238bceSAndroid Build Coastguard Worker m_intermediateResultBuffers.push_back(buffer);
2854*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "gen buffers");
2855*35238bceSAndroid Build Coastguard Worker }
2856*35238bceSAndroid Build Coastguard Worker
2857*35238bceSAndroid Build Coastguard Worker // gen programs
2858*35238bceSAndroid Build Coastguard Worker
2859*35238bceSAndroid Build Coastguard Worker m_program = new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources()
2860*35238bceSAndroid Build Coastguard Worker << glu::ComputeSource(genComputeSource()));
2861*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << *m_program;
2862*35238bceSAndroid Build Coastguard Worker if (!m_program->isOk())
2863*35238bceSAndroid Build Coastguard Worker throw tcu::TestError("could not build program");
2864*35238bceSAndroid Build Coastguard Worker
2865*35238bceSAndroid Build Coastguard Worker m_imageReadProgram = new glu::ShaderProgram(m_context.getRenderContext(),
2866*35238bceSAndroid Build Coastguard Worker glu::ProgramSources() << glu::ComputeSource(genImageReadSource()));
2867*35238bceSAndroid Build Coastguard Worker if (!m_imageReadProgram->isOk())
2868*35238bceSAndroid Build Coastguard Worker {
2869*35238bceSAndroid Build Coastguard Worker const tcu::ScopedLogSection section(m_testCtx.getLog(), "ImageReadProgram", "Image read program");
2870*35238bceSAndroid Build Coastguard Worker
2871*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << *m_imageReadProgram;
2872*35238bceSAndroid Build Coastguard Worker throw tcu::TestError("could not build program");
2873*35238bceSAndroid Build Coastguard Worker }
2874*35238bceSAndroid Build Coastguard Worker
2875*35238bceSAndroid Build Coastguard Worker m_imageClearProgram = new glu::ShaderProgram(m_context.getRenderContext(),
2876*35238bceSAndroid Build Coastguard Worker glu::ProgramSources() << glu::ComputeSource(genImageClearSource()));
2877*35238bceSAndroid Build Coastguard Worker if (!m_imageClearProgram->isOk())
2878*35238bceSAndroid Build Coastguard Worker {
2879*35238bceSAndroid Build Coastguard Worker const tcu::ScopedLogSection section(m_testCtx.getLog(), "ImageClearProgram", "Image read program");
2880*35238bceSAndroid Build Coastguard Worker
2881*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << *m_imageClearProgram;
2882*35238bceSAndroid Build Coastguard Worker throw tcu::TestError("could not build program");
2883*35238bceSAndroid Build Coastguard Worker }
2884*35238bceSAndroid Build Coastguard Worker }
2885*35238bceSAndroid Build Coastguard Worker
deinit(void)2886*35238bceSAndroid Build Coastguard Worker void ConcurrentImageAtomicCase::deinit(void)
2887*35238bceSAndroid Build Coastguard Worker {
2888*35238bceSAndroid Build Coastguard Worker if (m_imageID)
2889*35238bceSAndroid Build Coastguard Worker {
2890*35238bceSAndroid Build Coastguard Worker m_context.getRenderContext().getFunctions().deleteTextures(1, &m_imageID);
2891*35238bceSAndroid Build Coastguard Worker m_imageID = 0;
2892*35238bceSAndroid Build Coastguard Worker }
2893*35238bceSAndroid Build Coastguard Worker
2894*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < (int)m_intermediateResultBuffers.size(); ++ndx)
2895*35238bceSAndroid Build Coastguard Worker m_context.getRenderContext().getFunctions().deleteBuffers(1, &m_intermediateResultBuffers[ndx]);
2896*35238bceSAndroid Build Coastguard Worker m_intermediateResultBuffers.clear();
2897*35238bceSAndroid Build Coastguard Worker
2898*35238bceSAndroid Build Coastguard Worker delete m_program;
2899*35238bceSAndroid Build Coastguard Worker m_program = DE_NULL;
2900*35238bceSAndroid Build Coastguard Worker
2901*35238bceSAndroid Build Coastguard Worker delete m_imageReadProgram;
2902*35238bceSAndroid Build Coastguard Worker m_imageReadProgram = DE_NULL;
2903*35238bceSAndroid Build Coastguard Worker
2904*35238bceSAndroid Build Coastguard Worker delete m_imageClearProgram;
2905*35238bceSAndroid Build Coastguard Worker m_imageClearProgram = DE_NULL;
2906*35238bceSAndroid Build Coastguard Worker }
2907*35238bceSAndroid Build Coastguard Worker
iterate(void)2908*35238bceSAndroid Build Coastguard Worker TestCase::IterateResult ConcurrentImageAtomicCase::iterate(void)
2909*35238bceSAndroid Build Coastguard Worker {
2910*35238bceSAndroid Build Coastguard Worker const glw::Functions &gl = m_context.getRenderContext().getFunctions();
2911*35238bceSAndroid Build Coastguard Worker const uint32_t sumValue = (uint32_t)(m_numCalls * (m_numCalls + 1) / 2);
2912*35238bceSAndroid Build Coastguard Worker std::vector<int> deltas;
2913*35238bceSAndroid Build Coastguard Worker
2914*35238bceSAndroid Build Coastguard Worker // generate unique deltas
2915*35238bceSAndroid Build Coastguard Worker generateShuffledRamp(m_numCalls, deltas);
2916*35238bceSAndroid Build Coastguard Worker
2917*35238bceSAndroid Build Coastguard Worker // clear image
2918*35238bceSAndroid Build Coastguard Worker {
2919*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Clearing image contents" << tcu::TestLog::EndMessage;
2920*35238bceSAndroid Build Coastguard Worker
2921*35238bceSAndroid Build Coastguard Worker gl.useProgram(m_imageClearProgram->getProgram());
2922*35238bceSAndroid Build Coastguard Worker gl.bindImageTexture(2, m_imageID, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_R32UI);
2923*35238bceSAndroid Build Coastguard Worker gl.dispatchCompute(m_workSize, m_workSize, 1);
2924*35238bceSAndroid Build Coastguard Worker gl.memoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
2925*35238bceSAndroid Build Coastguard Worker
2926*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "clear");
2927*35238bceSAndroid Build Coastguard Worker }
2928*35238bceSAndroid Build Coastguard Worker
2929*35238bceSAndroid Build Coastguard Worker // invoke program N times, each with a different delta
2930*35238bceSAndroid Build Coastguard Worker {
2931*35238bceSAndroid Build Coastguard Worker const int deltaLocation = gl.getUniformLocation(m_program->getProgram(), "u_atomicDelta");
2932*35238bceSAndroid Build Coastguard Worker
2933*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Running shader " << m_numCalls << " times.\n"
2934*35238bceSAndroid Build Coastguard Worker << "Num groups = (" << m_workSize << ", " << m_workSize << ", 1)\n"
2935*35238bceSAndroid Build Coastguard Worker << "Setting u_atomicDelta to a unique value for each call.\n"
2936*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
2937*35238bceSAndroid Build Coastguard Worker
2938*35238bceSAndroid Build Coastguard Worker if (deltaLocation == -1)
2939*35238bceSAndroid Build Coastguard Worker throw tcu::TestError("u_atomicDelta location was -1");
2940*35238bceSAndroid Build Coastguard Worker
2941*35238bceSAndroid Build Coastguard Worker gl.useProgram(m_program->getProgram());
2942*35238bceSAndroid Build Coastguard Worker gl.bindImageTexture(2, m_imageID, 0, GL_FALSE, 0, GL_READ_WRITE, GL_R32UI);
2943*35238bceSAndroid Build Coastguard Worker
2944*35238bceSAndroid Build Coastguard Worker for (int callNdx = 0; callNdx < m_numCalls; ++callNdx)
2945*35238bceSAndroid Build Coastguard Worker {
2946*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Call " << callNdx << ": u_atomicDelta = " << deltas[callNdx]
2947*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
2948*35238bceSAndroid Build Coastguard Worker
2949*35238bceSAndroid Build Coastguard Worker gl.uniform1ui(deltaLocation, deltas[callNdx]);
2950*35238bceSAndroid Build Coastguard Worker gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_intermediateResultBuffers[callNdx]);
2951*35238bceSAndroid Build Coastguard Worker gl.dispatchCompute(m_workSize, m_workSize, 1);
2952*35238bceSAndroid Build Coastguard Worker }
2953*35238bceSAndroid Build Coastguard Worker
2954*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "post dispatch");
2955*35238bceSAndroid Build Coastguard Worker }
2956*35238bceSAndroid Build Coastguard Worker
2957*35238bceSAndroid Build Coastguard Worker // Verify result
2958*35238bceSAndroid Build Coastguard Worker {
2959*35238bceSAndroid Build Coastguard Worker std::vector<uint32_t> result;
2960*35238bceSAndroid Build Coastguard Worker
2961*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Verifying work image, it should be filled with value "
2962*35238bceSAndroid Build Coastguard Worker << sumValue << tcu::TestLog::EndMessage;
2963*35238bceSAndroid Build Coastguard Worker
2964*35238bceSAndroid Build Coastguard Worker readWorkImage(result);
2965*35238bceSAndroid Build Coastguard Worker
2966*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < m_workSize * m_workSize; ++ndx)
2967*35238bceSAndroid Build Coastguard Worker {
2968*35238bceSAndroid Build Coastguard Worker if (result[ndx] != sumValue)
2969*35238bceSAndroid Build Coastguard Worker {
2970*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Work image error, at index (" << ndx % m_workSize
2971*35238bceSAndroid Build Coastguard Worker << ", " << ndx / m_workSize << ") expected value " << (sumValue) << ", got "
2972*35238bceSAndroid Build Coastguard Worker << result[ndx] << "\n"
2973*35238bceSAndroid Build Coastguard Worker << "Work image contains invalid values." << tcu::TestLog::EndMessage;
2974*35238bceSAndroid Build Coastguard Worker
2975*35238bceSAndroid Build Coastguard Worker m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image contents invalid");
2976*35238bceSAndroid Build Coastguard Worker return STOP;
2977*35238bceSAndroid Build Coastguard Worker }
2978*35238bceSAndroid Build Coastguard Worker }
2979*35238bceSAndroid Build Coastguard Worker
2980*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Work image contents are valid." << tcu::TestLog::EndMessage;
2981*35238bceSAndroid Build Coastguard Worker }
2982*35238bceSAndroid Build Coastguard Worker
2983*35238bceSAndroid Build Coastguard Worker // verify steps
2984*35238bceSAndroid Build Coastguard Worker {
2985*35238bceSAndroid Build Coastguard Worker std::vector<std::vector<uint32_t>> intermediateResults(m_numCalls);
2986*35238bceSAndroid Build Coastguard Worker std::vector<uint32_t> valueChain(m_numCalls);
2987*35238bceSAndroid Build Coastguard Worker std::vector<uint32_t> chainDelta(m_numCalls);
2988*35238bceSAndroid Build Coastguard Worker
2989*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Verifying intermediate results. " << tcu::TestLog::EndMessage;
2990*35238bceSAndroid Build Coastguard Worker
2991*35238bceSAndroid Build Coastguard Worker // collect results
2992*35238bceSAndroid Build Coastguard Worker
2993*35238bceSAndroid Build Coastguard Worker for (int callNdx = 0; callNdx < m_numCalls; ++callNdx)
2994*35238bceSAndroid Build Coastguard Worker {
2995*35238bceSAndroid Build Coastguard Worker gl.bindBuffer(GL_SHADER_STORAGE_BUFFER, m_intermediateResultBuffers[callNdx]);
2996*35238bceSAndroid Build Coastguard Worker readBuffer(gl, GL_SHADER_STORAGE_BUFFER, m_workSize * m_workSize, intermediateResults[callNdx]);
2997*35238bceSAndroid Build Coastguard Worker }
2998*35238bceSAndroid Build Coastguard Worker
2999*35238bceSAndroid Build Coastguard Worker // verify values
3000*35238bceSAndroid Build Coastguard Worker
3001*35238bceSAndroid Build Coastguard Worker for (int valueNdx = 0; valueNdx < m_workSize; ++valueNdx)
3002*35238bceSAndroid Build Coastguard Worker {
3003*35238bceSAndroid Build Coastguard Worker int invalidOperationNdx;
3004*35238bceSAndroid Build Coastguard Worker uint32_t errorDelta;
3005*35238bceSAndroid Build Coastguard Worker uint32_t errorExpected;
3006*35238bceSAndroid Build Coastguard Worker
3007*35238bceSAndroid Build Coastguard Worker // collect result chain for each element
3008*35238bceSAndroid Build Coastguard Worker for (int callNdx = 0; callNdx < m_numCalls; ++callNdx)
3009*35238bceSAndroid Build Coastguard Worker valueChain[callNdx] = intermediateResults[callNdx][valueNdx];
3010*35238bceSAndroid Build Coastguard Worker
3011*35238bceSAndroid Build Coastguard Worker // check there exists a path from 0 to sumValue using each addition once
3012*35238bceSAndroid Build Coastguard Worker // decompose cumulative results to addition operations (all additions positive => this works)
3013*35238bceSAndroid Build Coastguard Worker
3014*35238bceSAndroid Build Coastguard Worker std::sort(valueChain.begin(), valueChain.end());
3015*35238bceSAndroid Build Coastguard Worker
3016*35238bceSAndroid Build Coastguard Worker for (int callNdx = 0; callNdx < m_numCalls; ++callNdx)
3017*35238bceSAndroid Build Coastguard Worker chainDelta[callNdx] =
3018*35238bceSAndroid Build Coastguard Worker ((callNdx + 1 == m_numCalls) ? (sumValue) : (valueChain[callNdx + 1])) - valueChain[callNdx];
3019*35238bceSAndroid Build Coastguard Worker
3020*35238bceSAndroid Build Coastguard Worker // chainDelta contains now the actual additions applied to the value
3021*35238bceSAndroid Build Coastguard Worker std::sort(chainDelta.begin(), chainDelta.end());
3022*35238bceSAndroid Build Coastguard Worker
3023*35238bceSAndroid Build Coastguard Worker // validate chain
3024*35238bceSAndroid Build Coastguard Worker if (!validateSortedAtomicRampAdditionValueChain(valueChain, sumValue, invalidOperationNdx, errorDelta,
3025*35238bceSAndroid Build Coastguard Worker errorExpected))
3026*35238bceSAndroid Build Coastguard Worker {
3027*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Intermediate buffer error, at index ("
3028*35238bceSAndroid Build Coastguard Worker << valueNdx % m_workSize << ", " << valueNdx / m_workSize
3029*35238bceSAndroid Build Coastguard Worker << "), applied operation index " << invalidOperationNdx
3030*35238bceSAndroid Build Coastguard Worker << ", value was increased by " << errorDelta << ", but expected " << errorExpected
3031*35238bceSAndroid Build Coastguard Worker << ".\n"
3032*35238bceSAndroid Build Coastguard Worker << "Intermediate buffer contains invalid values. Values at index ("
3033*35238bceSAndroid Build Coastguard Worker << valueNdx % m_workSize << ", " << valueNdx / m_workSize << ")\n"
3034*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
3035*35238bceSAndroid Build Coastguard Worker
3036*35238bceSAndroid Build Coastguard Worker for (int logCallNdx = 0; logCallNdx < m_numCalls; ++logCallNdx)
3037*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Value[" << logCallNdx
3038*35238bceSAndroid Build Coastguard Worker << "] = " << intermediateResults[logCallNdx][valueNdx]
3039*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
3040*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Result = " << sumValue << tcu::TestLog::EndMessage;
3041*35238bceSAndroid Build Coastguard Worker
3042*35238bceSAndroid Build Coastguard Worker m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Buffer contents invalid");
3043*35238bceSAndroid Build Coastguard Worker return STOP;
3044*35238bceSAndroid Build Coastguard Worker }
3045*35238bceSAndroid Build Coastguard Worker }
3046*35238bceSAndroid Build Coastguard Worker
3047*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Intermediate buffers are valid." << tcu::TestLog::EndMessage;
3048*35238bceSAndroid Build Coastguard Worker }
3049*35238bceSAndroid Build Coastguard Worker
3050*35238bceSAndroid Build Coastguard Worker m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
3051*35238bceSAndroid Build Coastguard Worker return STOP;
3052*35238bceSAndroid Build Coastguard Worker }
3053*35238bceSAndroid Build Coastguard Worker
readWorkImage(std::vector<uint32_t> & result)3054*35238bceSAndroid Build Coastguard Worker void ConcurrentImageAtomicCase::readWorkImage(std::vector<uint32_t> &result)
3055*35238bceSAndroid Build Coastguard Worker {
3056*35238bceSAndroid Build Coastguard Worker const glw::Functions &gl = m_context.getRenderContext().getFunctions();
3057*35238bceSAndroid Build Coastguard Worker glu::Buffer resultBuffer(m_context.getRenderContext());
3058*35238bceSAndroid Build Coastguard Worker
3059*35238bceSAndroid Build Coastguard Worker // Read image to an ssbo
3060*35238bceSAndroid Build Coastguard Worker
3061*35238bceSAndroid Build Coastguard Worker {
3062*35238bceSAndroid Build Coastguard Worker const std::vector<uint32_t> zeroData(m_workSize * m_workSize, 0);
3063*35238bceSAndroid Build Coastguard Worker
3064*35238bceSAndroid Build Coastguard Worker gl.bindBuffer(GL_SHADER_STORAGE_BUFFER, *resultBuffer);
3065*35238bceSAndroid Build Coastguard Worker gl.bufferData(GL_SHADER_STORAGE_BUFFER, (int)(sizeof(uint32_t) * m_workSize * m_workSize), &zeroData[0],
3066*35238bceSAndroid Build Coastguard Worker GL_DYNAMIC_COPY);
3067*35238bceSAndroid Build Coastguard Worker
3068*35238bceSAndroid Build Coastguard Worker gl.memoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
3069*35238bceSAndroid Build Coastguard Worker gl.useProgram(m_imageReadProgram->getProgram());
3070*35238bceSAndroid Build Coastguard Worker
3071*35238bceSAndroid Build Coastguard Worker gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, *resultBuffer);
3072*35238bceSAndroid Build Coastguard Worker gl.bindImageTexture(2, m_imageID, 0, GL_FALSE, 0, GL_READ_ONLY, GL_R32UI);
3073*35238bceSAndroid Build Coastguard Worker gl.dispatchCompute(m_workSize, m_workSize, 1);
3074*35238bceSAndroid Build Coastguard Worker
3075*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "read");
3076*35238bceSAndroid Build Coastguard Worker }
3077*35238bceSAndroid Build Coastguard Worker
3078*35238bceSAndroid Build Coastguard Worker // Read ssbo
3079*35238bceSAndroid Build Coastguard Worker {
3080*35238bceSAndroid Build Coastguard Worker const void *ptr = gl.mapBufferRange(GL_SHADER_STORAGE_BUFFER, 0,
3081*35238bceSAndroid Build Coastguard Worker (int)(sizeof(uint32_t) * m_workSize * m_workSize), GL_MAP_READ_BIT);
3082*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "map");
3083*35238bceSAndroid Build Coastguard Worker
3084*35238bceSAndroid Build Coastguard Worker if (!ptr)
3085*35238bceSAndroid Build Coastguard Worker throw tcu::TestError("mapBufferRange returned NULL");
3086*35238bceSAndroid Build Coastguard Worker
3087*35238bceSAndroid Build Coastguard Worker result.resize(m_workSize * m_workSize);
3088*35238bceSAndroid Build Coastguard Worker memcpy(&result[0], ptr, sizeof(uint32_t) * m_workSize * m_workSize);
3089*35238bceSAndroid Build Coastguard Worker
3090*35238bceSAndroid Build Coastguard Worker if (gl.unmapBuffer(GL_SHADER_STORAGE_BUFFER) == GL_FALSE)
3091*35238bceSAndroid Build Coastguard Worker throw tcu::TestError("unmapBuffer returned false");
3092*35238bceSAndroid Build Coastguard Worker }
3093*35238bceSAndroid Build Coastguard Worker }
3094*35238bceSAndroid Build Coastguard Worker
genComputeSource(void) const3095*35238bceSAndroid Build Coastguard Worker std::string ConcurrentImageAtomicCase::genComputeSource(void) const
3096*35238bceSAndroid Build Coastguard Worker {
3097*35238bceSAndroid Build Coastguard Worker std::ostringstream buf;
3098*35238bceSAndroid Build Coastguard Worker
3099*35238bceSAndroid Build Coastguard Worker buf << "${GLSL_VERSION_DECL}\n"
3100*35238bceSAndroid Build Coastguard Worker << "${SHADER_IMAGE_ATOMIC_REQUIRE}\n"
3101*35238bceSAndroid Build Coastguard Worker << "\n"
3102*35238bceSAndroid Build Coastguard Worker << "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
3103*35238bceSAndroid Build Coastguard Worker << "layout (binding = 1, std430) writeonly buffer IntermediateResults\n"
3104*35238bceSAndroid Build Coastguard Worker << "{\n"
3105*35238bceSAndroid Build Coastguard Worker << " highp uint values[" << m_workSize * m_workSize << "];\n"
3106*35238bceSAndroid Build Coastguard Worker << "} sb_ires;\n"
3107*35238bceSAndroid Build Coastguard Worker << "\n"
3108*35238bceSAndroid Build Coastguard Worker << "layout (binding = 2, r32ui) volatile uniform highp uimage2D u_workImage;\n"
3109*35238bceSAndroid Build Coastguard Worker << "uniform highp uint u_atomicDelta;\n"
3110*35238bceSAndroid Build Coastguard Worker << "\n"
3111*35238bceSAndroid Build Coastguard Worker << "void main ()\n"
3112*35238bceSAndroid Build Coastguard Worker << "{\n"
3113*35238bceSAndroid Build Coastguard Worker << " highp uint invocationIndex = gl_GlobalInvocationID.x + gl_GlobalInvocationID.y * uint(" << m_workSize
3114*35238bceSAndroid Build Coastguard Worker << ");\n"
3115*35238bceSAndroid Build Coastguard Worker << " sb_ires.values[invocationIndex] = imageAtomicAdd(u_workImage, ivec2(gl_GlobalInvocationID.xy), "
3116*35238bceSAndroid Build Coastguard Worker "u_atomicDelta);\n"
3117*35238bceSAndroid Build Coastguard Worker << "}";
3118*35238bceSAndroid Build Coastguard Worker
3119*35238bceSAndroid Build Coastguard Worker return specializeShader(m_context, buf.str().c_str());
3120*35238bceSAndroid Build Coastguard Worker }
3121*35238bceSAndroid Build Coastguard Worker
genImageReadSource(void) const3122*35238bceSAndroid Build Coastguard Worker std::string ConcurrentImageAtomicCase::genImageReadSource(void) const
3123*35238bceSAndroid Build Coastguard Worker {
3124*35238bceSAndroid Build Coastguard Worker std::ostringstream buf;
3125*35238bceSAndroid Build Coastguard Worker
3126*35238bceSAndroid Build Coastguard Worker buf << "${GLSL_VERSION_DECL}\n"
3127*35238bceSAndroid Build Coastguard Worker << "\n"
3128*35238bceSAndroid Build Coastguard Worker << "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
3129*35238bceSAndroid Build Coastguard Worker << "layout (binding = 1, std430) writeonly buffer ImageValues\n"
3130*35238bceSAndroid Build Coastguard Worker << "{\n"
3131*35238bceSAndroid Build Coastguard Worker << " highp uint values[" << m_workSize * m_workSize << "];\n"
3132*35238bceSAndroid Build Coastguard Worker << "} sb_res;\n"
3133*35238bceSAndroid Build Coastguard Worker << "\n"
3134*35238bceSAndroid Build Coastguard Worker << "layout (binding = 2, r32ui) readonly uniform highp uimage2D u_workImage;\n"
3135*35238bceSAndroid Build Coastguard Worker << "\n"
3136*35238bceSAndroid Build Coastguard Worker << "void main ()\n"
3137*35238bceSAndroid Build Coastguard Worker << "{\n"
3138*35238bceSAndroid Build Coastguard Worker << " highp uint invocationIndex = gl_GlobalInvocationID.x + gl_GlobalInvocationID.y * uint(" << m_workSize
3139*35238bceSAndroid Build Coastguard Worker << ");\n"
3140*35238bceSAndroid Build Coastguard Worker << " sb_res.values[invocationIndex] = imageLoad(u_workImage, ivec2(gl_GlobalInvocationID.xy)).x;\n"
3141*35238bceSAndroid Build Coastguard Worker << "}";
3142*35238bceSAndroid Build Coastguard Worker
3143*35238bceSAndroid Build Coastguard Worker return specializeShader(m_context, buf.str().c_str());
3144*35238bceSAndroid Build Coastguard Worker }
3145*35238bceSAndroid Build Coastguard Worker
genImageClearSource(void) const3146*35238bceSAndroid Build Coastguard Worker std::string ConcurrentImageAtomicCase::genImageClearSource(void) const
3147*35238bceSAndroid Build Coastguard Worker {
3148*35238bceSAndroid Build Coastguard Worker std::ostringstream buf;
3149*35238bceSAndroid Build Coastguard Worker
3150*35238bceSAndroid Build Coastguard Worker buf << "${GLSL_VERSION_DECL}\n"
3151*35238bceSAndroid Build Coastguard Worker << "\n"
3152*35238bceSAndroid Build Coastguard Worker << "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
3153*35238bceSAndroid Build Coastguard Worker << "layout (binding = 2, r32ui) writeonly uniform highp uimage2D u_workImage;\n"
3154*35238bceSAndroid Build Coastguard Worker << "\n"
3155*35238bceSAndroid Build Coastguard Worker << "void main ()\n"
3156*35238bceSAndroid Build Coastguard Worker << "{\n"
3157*35238bceSAndroid Build Coastguard Worker << " imageStore(u_workImage, ivec2(gl_GlobalInvocationID.xy), uvec4(0, 0, 0, 0));\n"
3158*35238bceSAndroid Build Coastguard Worker << "}";
3159*35238bceSAndroid Build Coastguard Worker
3160*35238bceSAndroid Build Coastguard Worker return specializeShader(m_context, buf.str().c_str());
3161*35238bceSAndroid Build Coastguard Worker }
3162*35238bceSAndroid Build Coastguard Worker
3163*35238bceSAndroid Build Coastguard Worker class ConcurrentSSBOAtomicCounterMixedCase : public TestCase
3164*35238bceSAndroid Build Coastguard Worker {
3165*35238bceSAndroid Build Coastguard Worker public:
3166*35238bceSAndroid Build Coastguard Worker ConcurrentSSBOAtomicCounterMixedCase(Context &context, const char *name, const char *description, int numCalls,
3167*35238bceSAndroid Build Coastguard Worker int workSize);
3168*35238bceSAndroid Build Coastguard Worker ~ConcurrentSSBOAtomicCounterMixedCase(void);
3169*35238bceSAndroid Build Coastguard Worker
3170*35238bceSAndroid Build Coastguard Worker void init(void);
3171*35238bceSAndroid Build Coastguard Worker void deinit(void);
3172*35238bceSAndroid Build Coastguard Worker IterateResult iterate(void);
3173*35238bceSAndroid Build Coastguard Worker
3174*35238bceSAndroid Build Coastguard Worker private:
3175*35238bceSAndroid Build Coastguard Worker std::string genSSBOComputeSource(void) const;
3176*35238bceSAndroid Build Coastguard Worker std::string genAtomicCounterComputeSource(void) const;
3177*35238bceSAndroid Build Coastguard Worker
3178*35238bceSAndroid Build Coastguard Worker const int m_numCalls;
3179*35238bceSAndroid Build Coastguard Worker const int m_workSize;
3180*35238bceSAndroid Build Coastguard Worker uint32_t m_bufferID;
3181*35238bceSAndroid Build Coastguard Worker glu::ShaderProgram *m_ssboAtomicProgram;
3182*35238bceSAndroid Build Coastguard Worker glu::ShaderProgram *m_atomicCounterProgram;
3183*35238bceSAndroid Build Coastguard Worker };
3184*35238bceSAndroid Build Coastguard Worker
ConcurrentSSBOAtomicCounterMixedCase(Context & context,const char * name,const char * description,int numCalls,int workSize)3185*35238bceSAndroid Build Coastguard Worker ConcurrentSSBOAtomicCounterMixedCase::ConcurrentSSBOAtomicCounterMixedCase(Context &context, const char *name,
3186*35238bceSAndroid Build Coastguard Worker const char *description, int numCalls,
3187*35238bceSAndroid Build Coastguard Worker int workSize)
3188*35238bceSAndroid Build Coastguard Worker : TestCase(context, name, description)
3189*35238bceSAndroid Build Coastguard Worker , m_numCalls(numCalls)
3190*35238bceSAndroid Build Coastguard Worker , m_workSize(workSize)
3191*35238bceSAndroid Build Coastguard Worker , m_bufferID(DE_NULL)
3192*35238bceSAndroid Build Coastguard Worker , m_ssboAtomicProgram(DE_NULL)
3193*35238bceSAndroid Build Coastguard Worker , m_atomicCounterProgram(DE_NULL)
3194*35238bceSAndroid Build Coastguard Worker {
3195*35238bceSAndroid Build Coastguard Worker // SSBO atomic XORs cancel out
3196*35238bceSAndroid Build Coastguard Worker DE_ASSERT((workSize * numCalls) % (16 * 2) == 0);
3197*35238bceSAndroid Build Coastguard Worker }
3198*35238bceSAndroid Build Coastguard Worker
~ConcurrentSSBOAtomicCounterMixedCase(void)3199*35238bceSAndroid Build Coastguard Worker ConcurrentSSBOAtomicCounterMixedCase::~ConcurrentSSBOAtomicCounterMixedCase(void)
3200*35238bceSAndroid Build Coastguard Worker {
3201*35238bceSAndroid Build Coastguard Worker deinit();
3202*35238bceSAndroid Build Coastguard Worker }
3203*35238bceSAndroid Build Coastguard Worker
init(void)3204*35238bceSAndroid Build Coastguard Worker void ConcurrentSSBOAtomicCounterMixedCase::init(void)
3205*35238bceSAndroid Build Coastguard Worker {
3206*35238bceSAndroid Build Coastguard Worker const glw::Functions &gl = m_context.getRenderContext().getFunctions();
3207*35238bceSAndroid Build Coastguard Worker const uint32_t zeroBuf[2] = {0, 0};
3208*35238bceSAndroid Build Coastguard Worker
3209*35238bceSAndroid Build Coastguard Worker // gen buffer
3210*35238bceSAndroid Build Coastguard Worker
3211*35238bceSAndroid Build Coastguard Worker gl.genBuffers(1, &m_bufferID);
3212*35238bceSAndroid Build Coastguard Worker gl.bindBuffer(GL_SHADER_STORAGE_BUFFER, m_bufferID);
3213*35238bceSAndroid Build Coastguard Worker gl.bufferData(GL_SHADER_STORAGE_BUFFER, (int)(sizeof(uint32_t) * 2), zeroBuf, GL_DYNAMIC_COPY);
3214*35238bceSAndroid Build Coastguard Worker
3215*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "gen buffers");
3216*35238bceSAndroid Build Coastguard Worker
3217*35238bceSAndroid Build Coastguard Worker // gen programs
3218*35238bceSAndroid Build Coastguard Worker
3219*35238bceSAndroid Build Coastguard Worker {
3220*35238bceSAndroid Build Coastguard Worker const tcu::ScopedLogSection section(m_testCtx.getLog(), "SSBOProgram", "SSBO atomic program");
3221*35238bceSAndroid Build Coastguard Worker
3222*35238bceSAndroid Build Coastguard Worker m_ssboAtomicProgram = new glu::ShaderProgram(
3223*35238bceSAndroid Build Coastguard Worker m_context.getRenderContext(), glu::ProgramSources() << glu::ComputeSource(genSSBOComputeSource()));
3224*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << *m_ssboAtomicProgram;
3225*35238bceSAndroid Build Coastguard Worker if (!m_ssboAtomicProgram->isOk())
3226*35238bceSAndroid Build Coastguard Worker throw tcu::TestError("could not build program");
3227*35238bceSAndroid Build Coastguard Worker }
3228*35238bceSAndroid Build Coastguard Worker {
3229*35238bceSAndroid Build Coastguard Worker const tcu::ScopedLogSection section(m_testCtx.getLog(), "AtomicCounterProgram", "Atomic counter program");
3230*35238bceSAndroid Build Coastguard Worker
3231*35238bceSAndroid Build Coastguard Worker m_atomicCounterProgram = new glu::ShaderProgram(
3232*35238bceSAndroid Build Coastguard Worker m_context.getRenderContext(), glu::ProgramSources() << glu::ComputeSource(genAtomicCounterComputeSource()));
3233*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << *m_atomicCounterProgram;
3234*35238bceSAndroid Build Coastguard Worker if (!m_atomicCounterProgram->isOk())
3235*35238bceSAndroid Build Coastguard Worker throw tcu::TestError("could not build program");
3236*35238bceSAndroid Build Coastguard Worker }
3237*35238bceSAndroid Build Coastguard Worker }
3238*35238bceSAndroid Build Coastguard Worker
deinit(void)3239*35238bceSAndroid Build Coastguard Worker void ConcurrentSSBOAtomicCounterMixedCase::deinit(void)
3240*35238bceSAndroid Build Coastguard Worker {
3241*35238bceSAndroid Build Coastguard Worker if (m_bufferID)
3242*35238bceSAndroid Build Coastguard Worker {
3243*35238bceSAndroid Build Coastguard Worker m_context.getRenderContext().getFunctions().deleteBuffers(1, &m_bufferID);
3244*35238bceSAndroid Build Coastguard Worker m_bufferID = 0;
3245*35238bceSAndroid Build Coastguard Worker }
3246*35238bceSAndroid Build Coastguard Worker
3247*35238bceSAndroid Build Coastguard Worker delete m_ssboAtomicProgram;
3248*35238bceSAndroid Build Coastguard Worker m_ssboAtomicProgram = DE_NULL;
3249*35238bceSAndroid Build Coastguard Worker
3250*35238bceSAndroid Build Coastguard Worker delete m_atomicCounterProgram;
3251*35238bceSAndroid Build Coastguard Worker m_atomicCounterProgram = DE_NULL;
3252*35238bceSAndroid Build Coastguard Worker }
3253*35238bceSAndroid Build Coastguard Worker
iterate(void)3254*35238bceSAndroid Build Coastguard Worker TestCase::IterateResult ConcurrentSSBOAtomicCounterMixedCase::iterate(void)
3255*35238bceSAndroid Build Coastguard Worker {
3256*35238bceSAndroid Build Coastguard Worker const glw::Functions &gl = m_context.getRenderContext().getFunctions();
3257*35238bceSAndroid Build Coastguard Worker
3258*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message
3259*35238bceSAndroid Build Coastguard Worker << "Testing atomic counters and SSBO atomic operations with both backed by the same buffer."
3260*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
3261*35238bceSAndroid Build Coastguard Worker
3262*35238bceSAndroid Build Coastguard Worker // invoke programs N times
3263*35238bceSAndroid Build Coastguard Worker {
3264*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Running SSBO atomic program and atomic counter program "
3265*35238bceSAndroid Build Coastguard Worker << m_numCalls << " times. (interleaved)\n"
3266*35238bceSAndroid Build Coastguard Worker << "Num groups = (" << m_workSize << ", 1, 1)\n"
3267*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
3268*35238bceSAndroid Build Coastguard Worker
3269*35238bceSAndroid Build Coastguard Worker gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_bufferID);
3270*35238bceSAndroid Build Coastguard Worker gl.bindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0, m_bufferID);
3271*35238bceSAndroid Build Coastguard Worker
3272*35238bceSAndroid Build Coastguard Worker for (int callNdx = 0; callNdx < m_numCalls; ++callNdx)
3273*35238bceSAndroid Build Coastguard Worker {
3274*35238bceSAndroid Build Coastguard Worker gl.useProgram(m_atomicCounterProgram->getProgram());
3275*35238bceSAndroid Build Coastguard Worker gl.dispatchCompute(m_workSize, 1, 1);
3276*35238bceSAndroid Build Coastguard Worker
3277*35238bceSAndroid Build Coastguard Worker gl.useProgram(m_ssboAtomicProgram->getProgram());
3278*35238bceSAndroid Build Coastguard Worker gl.dispatchCompute(m_workSize, 1, 1);
3279*35238bceSAndroid Build Coastguard Worker }
3280*35238bceSAndroid Build Coastguard Worker
3281*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "post dispatch");
3282*35238bceSAndroid Build Coastguard Worker }
3283*35238bceSAndroid Build Coastguard Worker
3284*35238bceSAndroid Build Coastguard Worker // Verify result
3285*35238bceSAndroid Build Coastguard Worker {
3286*35238bceSAndroid Build Coastguard Worker uint32_t result;
3287*35238bceSAndroid Build Coastguard Worker
3288*35238bceSAndroid Build Coastguard Worker // XORs cancel out, only addition is left
3289*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Verifying work buffer, it should be " << m_numCalls * m_workSize
3290*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
3291*35238bceSAndroid Build Coastguard Worker
3292*35238bceSAndroid Build Coastguard Worker gl.bindBuffer(GL_ATOMIC_COUNTER_BUFFER, m_bufferID);
3293*35238bceSAndroid Build Coastguard Worker result = readBufferUint32(gl, GL_ATOMIC_COUNTER_BUFFER);
3294*35238bceSAndroid Build Coastguard Worker
3295*35238bceSAndroid Build Coastguard Worker if ((int)result != m_numCalls * m_workSize)
3296*35238bceSAndroid Build Coastguard Worker {
3297*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Buffer value error, expected value "
3298*35238bceSAndroid Build Coastguard Worker << (m_numCalls * m_workSize) << ", got " << result << "\n"
3299*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
3300*35238bceSAndroid Build Coastguard Worker
3301*35238bceSAndroid Build Coastguard Worker m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Buffer contents invalid");
3302*35238bceSAndroid Build Coastguard Worker return STOP;
3303*35238bceSAndroid Build Coastguard Worker }
3304*35238bceSAndroid Build Coastguard Worker
3305*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Buffer is valid." << tcu::TestLog::EndMessage;
3306*35238bceSAndroid Build Coastguard Worker }
3307*35238bceSAndroid Build Coastguard Worker
3308*35238bceSAndroid Build Coastguard Worker m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
3309*35238bceSAndroid Build Coastguard Worker return STOP;
3310*35238bceSAndroid Build Coastguard Worker }
3311*35238bceSAndroid Build Coastguard Worker
genSSBOComputeSource(void) const3312*35238bceSAndroid Build Coastguard Worker std::string ConcurrentSSBOAtomicCounterMixedCase::genSSBOComputeSource(void) const
3313*35238bceSAndroid Build Coastguard Worker {
3314*35238bceSAndroid Build Coastguard Worker std::ostringstream buf;
3315*35238bceSAndroid Build Coastguard Worker
3316*35238bceSAndroid Build Coastguard Worker buf << "${GLSL_VERSION_DECL}\n"
3317*35238bceSAndroid Build Coastguard Worker << "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
3318*35238bceSAndroid Build Coastguard Worker << "layout (binding = 1, std430) volatile buffer WorkBuffer\n"
3319*35238bceSAndroid Build Coastguard Worker << "{\n"
3320*35238bceSAndroid Build Coastguard Worker << " highp uint targetValue;\n"
3321*35238bceSAndroid Build Coastguard Worker << " highp uint unused;\n"
3322*35238bceSAndroid Build Coastguard Worker << "} sb_work;\n"
3323*35238bceSAndroid Build Coastguard Worker << "\n"
3324*35238bceSAndroid Build Coastguard Worker << "void main ()\n"
3325*35238bceSAndroid Build Coastguard Worker << "{\n"
3326*35238bceSAndroid Build Coastguard Worker << " // flip high bits\n"
3327*35238bceSAndroid Build Coastguard Worker << " highp uint mask = uint(1) << (24u + (gl_GlobalInvocationID.x % 8u));\n"
3328*35238bceSAndroid Build Coastguard Worker << " sb_work.unused = atomicXor(sb_work.targetValue, mask);\n"
3329*35238bceSAndroid Build Coastguard Worker << "}";
3330*35238bceSAndroid Build Coastguard Worker
3331*35238bceSAndroid Build Coastguard Worker return specializeShader(m_context, buf.str().c_str());
3332*35238bceSAndroid Build Coastguard Worker }
3333*35238bceSAndroid Build Coastguard Worker
genAtomicCounterComputeSource(void) const3334*35238bceSAndroid Build Coastguard Worker std::string ConcurrentSSBOAtomicCounterMixedCase::genAtomicCounterComputeSource(void) const
3335*35238bceSAndroid Build Coastguard Worker {
3336*35238bceSAndroid Build Coastguard Worker std::ostringstream buf;
3337*35238bceSAndroid Build Coastguard Worker
3338*35238bceSAndroid Build Coastguard Worker buf << "${GLSL_VERSION_DECL}\n"
3339*35238bceSAndroid Build Coastguard Worker << "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
3340*35238bceSAndroid Build Coastguard Worker << "\n"
3341*35238bceSAndroid Build Coastguard Worker << "layout (binding = 0, offset = 0) uniform atomic_uint u_counter;\n"
3342*35238bceSAndroid Build Coastguard Worker << "\n"
3343*35238bceSAndroid Build Coastguard Worker << "void main ()\n"
3344*35238bceSAndroid Build Coastguard Worker << "{\n"
3345*35238bceSAndroid Build Coastguard Worker << " atomicCounterIncrement(u_counter);\n"
3346*35238bceSAndroid Build Coastguard Worker << "}";
3347*35238bceSAndroid Build Coastguard Worker
3348*35238bceSAndroid Build Coastguard Worker return specializeShader(m_context, buf.str().c_str());
3349*35238bceSAndroid Build Coastguard Worker }
3350*35238bceSAndroid Build Coastguard Worker
3351*35238bceSAndroid Build Coastguard Worker } // namespace
3352*35238bceSAndroid Build Coastguard Worker
SynchronizationTests(Context & context)3353*35238bceSAndroid Build Coastguard Worker SynchronizationTests::SynchronizationTests(Context &context)
3354*35238bceSAndroid Build Coastguard Worker : TestCaseGroup(context, "synchronization", "Synchronization tests")
3355*35238bceSAndroid Build Coastguard Worker {
3356*35238bceSAndroid Build Coastguard Worker }
3357*35238bceSAndroid Build Coastguard Worker
~SynchronizationTests(void)3358*35238bceSAndroid Build Coastguard Worker SynchronizationTests::~SynchronizationTests(void)
3359*35238bceSAndroid Build Coastguard Worker {
3360*35238bceSAndroid Build Coastguard Worker }
3361*35238bceSAndroid Build Coastguard Worker
init(void)3362*35238bceSAndroid Build Coastguard Worker void SynchronizationTests::init(void)
3363*35238bceSAndroid Build Coastguard Worker {
3364*35238bceSAndroid Build Coastguard Worker tcu::TestCaseGroup *const inInvocationGroup =
3365*35238bceSAndroid Build Coastguard Worker new tcu::TestCaseGroup(m_testCtx, "in_invocation", "Test intra-invocation synchronization");
3366*35238bceSAndroid Build Coastguard Worker tcu::TestCaseGroup *const interInvocationGroup =
3367*35238bceSAndroid Build Coastguard Worker new tcu::TestCaseGroup(m_testCtx, "inter_invocation", "Test inter-invocation synchronization");
3368*35238bceSAndroid Build Coastguard Worker tcu::TestCaseGroup *const interCallGroup =
3369*35238bceSAndroid Build Coastguard Worker new tcu::TestCaseGroup(m_testCtx, "inter_call", "Test inter-call synchronization");
3370*35238bceSAndroid Build Coastguard Worker
3371*35238bceSAndroid Build Coastguard Worker addChild(inInvocationGroup);
3372*35238bceSAndroid Build Coastguard Worker addChild(interInvocationGroup);
3373*35238bceSAndroid Build Coastguard Worker addChild(interCallGroup);
3374*35238bceSAndroid Build Coastguard Worker
3375*35238bceSAndroid Build Coastguard Worker // .in_invocation & .inter_invocation
3376*35238bceSAndroid Build Coastguard Worker {
3377*35238bceSAndroid Build Coastguard Worker static const struct CaseConfig
3378*35238bceSAndroid Build Coastguard Worker {
3379*35238bceSAndroid Build Coastguard Worker const char *namePrefix;
3380*35238bceSAndroid Build Coastguard Worker const InterInvocationTestCase::StorageType storage;
3381*35238bceSAndroid Build Coastguard Worker const int flags;
3382*35238bceSAndroid Build Coastguard Worker } configs[] = {
3383*35238bceSAndroid Build Coastguard Worker {"image", InterInvocationTestCase::STORAGE_IMAGE, 0},
3384*35238bceSAndroid Build Coastguard Worker {"image_atomic", InterInvocationTestCase::STORAGE_IMAGE, InterInvocationTestCase::FLAG_ATOMIC},
3385*35238bceSAndroid Build Coastguard Worker {"ssbo", InterInvocationTestCase::STORAGE_BUFFER, 0},
3386*35238bceSAndroid Build Coastguard Worker {"ssbo_atomic", InterInvocationTestCase::STORAGE_BUFFER, InterInvocationTestCase::FLAG_ATOMIC},
3387*35238bceSAndroid Build Coastguard Worker };
3388*35238bceSAndroid Build Coastguard Worker
3389*35238bceSAndroid Build Coastguard Worker for (int groupNdx = 0; groupNdx < 2; ++groupNdx)
3390*35238bceSAndroid Build Coastguard Worker {
3391*35238bceSAndroid Build Coastguard Worker tcu::TestCaseGroup *const targetGroup = (groupNdx == 0) ? (inInvocationGroup) : (interInvocationGroup);
3392*35238bceSAndroid Build Coastguard Worker const int extraFlags = (groupNdx == 0) ? (0) : (InterInvocationTestCase::FLAG_IN_GROUP);
3393*35238bceSAndroid Build Coastguard Worker
3394*35238bceSAndroid Build Coastguard Worker for (int configNdx = 0; configNdx < DE_LENGTH_OF_ARRAY(configs); ++configNdx)
3395*35238bceSAndroid Build Coastguard Worker {
3396*35238bceSAndroid Build Coastguard Worker const char *const target =
3397*35238bceSAndroid Build Coastguard Worker (configs[configNdx].storage == InterInvocationTestCase::STORAGE_BUFFER) ? ("buffer") : ("image");
3398*35238bceSAndroid Build Coastguard Worker
3399*35238bceSAndroid Build Coastguard Worker targetGroup->addChild(new InvocationWriteReadCase(
3400*35238bceSAndroid Build Coastguard Worker m_context, (std::string(configs[configNdx].namePrefix) + "_write_read").c_str(),
3401*35238bceSAndroid Build Coastguard Worker (std::string("Write to ") + target + " and read it").c_str(), configs[configNdx].storage,
3402*35238bceSAndroid Build Coastguard Worker configs[configNdx].flags | extraFlags));
3403*35238bceSAndroid Build Coastguard Worker
3404*35238bceSAndroid Build Coastguard Worker targetGroup->addChild(new InvocationReadWriteCase(
3405*35238bceSAndroid Build Coastguard Worker m_context, (std::string(configs[configNdx].namePrefix) + "_read_write").c_str(),
3406*35238bceSAndroid Build Coastguard Worker (std::string("Read form ") + target + " and then write to it").c_str(), configs[configNdx].storage,
3407*35238bceSAndroid Build Coastguard Worker configs[configNdx].flags | extraFlags));
3408*35238bceSAndroid Build Coastguard Worker
3409*35238bceSAndroid Build Coastguard Worker targetGroup->addChild(new InvocationOverWriteCase(
3410*35238bceSAndroid Build Coastguard Worker m_context, (std::string(configs[configNdx].namePrefix) + "_overwrite").c_str(),
3411*35238bceSAndroid Build Coastguard Worker (std::string("Write to ") + target + " twice and read it").c_str(), configs[configNdx].storage,
3412*35238bceSAndroid Build Coastguard Worker configs[configNdx].flags | extraFlags));
3413*35238bceSAndroid Build Coastguard Worker
3414*35238bceSAndroid Build Coastguard Worker targetGroup->addChild(new InvocationAliasWriteCase(
3415*35238bceSAndroid Build Coastguard Worker m_context, (std::string(configs[configNdx].namePrefix) + "_alias_write").c_str(),
3416*35238bceSAndroid Build Coastguard Worker (std::string("Write to aliasing ") + target + " and read it").c_str(),
3417*35238bceSAndroid Build Coastguard Worker InvocationAliasWriteCase::TYPE_WRITE, configs[configNdx].storage,
3418*35238bceSAndroid Build Coastguard Worker configs[configNdx].flags | extraFlags));
3419*35238bceSAndroid Build Coastguard Worker
3420*35238bceSAndroid Build Coastguard Worker targetGroup->addChild(new InvocationAliasWriteCase(
3421*35238bceSAndroid Build Coastguard Worker m_context, (std::string(configs[configNdx].namePrefix) + "_alias_overwrite").c_str(),
3422*35238bceSAndroid Build Coastguard Worker (std::string("Write to aliasing ") + target + "s and read it").c_str(),
3423*35238bceSAndroid Build Coastguard Worker InvocationAliasWriteCase::TYPE_OVERWRITE, configs[configNdx].storage,
3424*35238bceSAndroid Build Coastguard Worker configs[configNdx].flags | extraFlags));
3425*35238bceSAndroid Build Coastguard Worker }
3426*35238bceSAndroid Build Coastguard Worker }
3427*35238bceSAndroid Build Coastguard Worker }
3428*35238bceSAndroid Build Coastguard Worker
3429*35238bceSAndroid Build Coastguard Worker // .inter_call
3430*35238bceSAndroid Build Coastguard Worker {
3431*35238bceSAndroid Build Coastguard Worker tcu::TestCaseGroup *const withBarrierGroup =
3432*35238bceSAndroid Build Coastguard Worker new tcu::TestCaseGroup(m_testCtx, "with_memory_barrier", "Synchronize with memory barrier");
3433*35238bceSAndroid Build Coastguard Worker tcu::TestCaseGroup *const withoutBarrierGroup =
3434*35238bceSAndroid Build Coastguard Worker new tcu::TestCaseGroup(m_testCtx, "without_memory_barrier", "Synchronize without memory barrier");
3435*35238bceSAndroid Build Coastguard Worker
3436*35238bceSAndroid Build Coastguard Worker interCallGroup->addChild(withBarrierGroup);
3437*35238bceSAndroid Build Coastguard Worker interCallGroup->addChild(withoutBarrierGroup);
3438*35238bceSAndroid Build Coastguard Worker
3439*35238bceSAndroid Build Coastguard Worker // .with_memory_barrier
3440*35238bceSAndroid Build Coastguard Worker {
3441*35238bceSAndroid Build Coastguard Worker static const struct CaseConfig
3442*35238bceSAndroid Build Coastguard Worker {
3443*35238bceSAndroid Build Coastguard Worker const char *namePrefix;
3444*35238bceSAndroid Build Coastguard Worker const InterCallTestCase::StorageType storage;
3445*35238bceSAndroid Build Coastguard Worker const int flags;
3446*35238bceSAndroid Build Coastguard Worker } configs[] = {
3447*35238bceSAndroid Build Coastguard Worker {"image", InterCallTestCase::STORAGE_IMAGE, 0},
3448*35238bceSAndroid Build Coastguard Worker {"image_atomic", InterCallTestCase::STORAGE_IMAGE,
3449*35238bceSAndroid Build Coastguard Worker InterCallTestCase::FLAG_USE_ATOMIC | InterCallTestCase::FLAG_USE_INT},
3450*35238bceSAndroid Build Coastguard Worker {"ssbo", InterCallTestCase::STORAGE_BUFFER, 0},
3451*35238bceSAndroid Build Coastguard Worker {"ssbo_atomic", InterCallTestCase::STORAGE_BUFFER,
3452*35238bceSAndroid Build Coastguard Worker InterCallTestCase::FLAG_USE_ATOMIC | InterCallTestCase::FLAG_USE_INT},
3453*35238bceSAndroid Build Coastguard Worker };
3454*35238bceSAndroid Build Coastguard Worker
3455*35238bceSAndroid Build Coastguard Worker const int seed0 = 123;
3456*35238bceSAndroid Build Coastguard Worker const int seed1 = 457;
3457*35238bceSAndroid Build Coastguard Worker
3458*35238bceSAndroid Build Coastguard Worker for (int configNdx = 0; configNdx < DE_LENGTH_OF_ARRAY(configs); ++configNdx)
3459*35238bceSAndroid Build Coastguard Worker {
3460*35238bceSAndroid Build Coastguard Worker const char *const target =
3461*35238bceSAndroid Build Coastguard Worker (configs[configNdx].storage == InterCallTestCase::STORAGE_BUFFER) ? ("buffer") : ("image");
3462*35238bceSAndroid Build Coastguard Worker
3463*35238bceSAndroid Build Coastguard Worker withBarrierGroup->addChild(new InterCallTestCase(
3464*35238bceSAndroid Build Coastguard Worker m_context, (std::string(configs[configNdx].namePrefix) + "_write_read").c_str(),
3465*35238bceSAndroid Build Coastguard Worker (std::string("Write to ") + target + " and read it").c_str(), configs[configNdx].storage,
3466*35238bceSAndroid Build Coastguard Worker configs[configNdx].flags,
3467*35238bceSAndroid Build Coastguard Worker InterCallOperations()
3468*35238bceSAndroid Build Coastguard Worker << op::WriteData::Generate(1, seed0) << op::Barrier() << op::ReadData::Generate(1, seed0)));
3469*35238bceSAndroid Build Coastguard Worker
3470*35238bceSAndroid Build Coastguard Worker withBarrierGroup->addChild(new InterCallTestCase(
3471*35238bceSAndroid Build Coastguard Worker m_context, (std::string(configs[configNdx].namePrefix) + "_read_write").c_str(),
3472*35238bceSAndroid Build Coastguard Worker (std::string("Read from ") + target + " and then write to it").c_str(), configs[configNdx].storage,
3473*35238bceSAndroid Build Coastguard Worker configs[configNdx].flags,
3474*35238bceSAndroid Build Coastguard Worker InterCallOperations()
3475*35238bceSAndroid Build Coastguard Worker << op::ReadZeroData::Generate(1) << op::Barrier() << op::WriteData::Generate(1, seed0)));
3476*35238bceSAndroid Build Coastguard Worker
3477*35238bceSAndroid Build Coastguard Worker withBarrierGroup->addChild(new InterCallTestCase(
3478*35238bceSAndroid Build Coastguard Worker m_context, (std::string(configs[configNdx].namePrefix) + "_overwrite").c_str(),
3479*35238bceSAndroid Build Coastguard Worker (std::string("Write to ") + target + " twice and read it").c_str(), configs[configNdx].storage,
3480*35238bceSAndroid Build Coastguard Worker configs[configNdx].flags,
3481*35238bceSAndroid Build Coastguard Worker InterCallOperations()
3482*35238bceSAndroid Build Coastguard Worker << op::WriteData::Generate(1, seed0) << op::Barrier() << op::WriteData::Generate(1, seed1)
3483*35238bceSAndroid Build Coastguard Worker << op::Barrier() << op::ReadData::Generate(1, seed1)));
3484*35238bceSAndroid Build Coastguard Worker
3485*35238bceSAndroid Build Coastguard Worker withBarrierGroup->addChild(new InterCallTestCase(
3486*35238bceSAndroid Build Coastguard Worker m_context, (std::string(configs[configNdx].namePrefix) + "_multiple_write_read").c_str(),
3487*35238bceSAndroid Build Coastguard Worker (std::string("Write to multiple ") + target + "s and read them").c_str(),
3488*35238bceSAndroid Build Coastguard Worker configs[configNdx].storage, configs[configNdx].flags,
3489*35238bceSAndroid Build Coastguard Worker InterCallOperations() << op::WriteData::Generate(1, seed0) << op::WriteData::Generate(2, seed1)
3490*35238bceSAndroid Build Coastguard Worker << op::Barrier() << op::ReadMultipleData::Generate(1, seed0, 2, seed1)));
3491*35238bceSAndroid Build Coastguard Worker
3492*35238bceSAndroid Build Coastguard Worker withBarrierGroup->addChild(new InterCallTestCase(
3493*35238bceSAndroid Build Coastguard Worker m_context,
3494*35238bceSAndroid Build Coastguard Worker (std::string(configs[configNdx].namePrefix) + "_multiple_interleaved_write_read").c_str(),
3495*35238bceSAndroid Build Coastguard Worker (std::string("Write to same ") + target + " in multiple calls and read it").c_str(),
3496*35238bceSAndroid Build Coastguard Worker configs[configNdx].storage, configs[configNdx].flags,
3497*35238bceSAndroid Build Coastguard Worker InterCallOperations() << op::WriteDataInterleaved::Generate(1, seed0, true)
3498*35238bceSAndroid Build Coastguard Worker << op::WriteDataInterleaved::Generate(1, seed1, false) << op::Barrier()
3499*35238bceSAndroid Build Coastguard Worker << op::ReadDataInterleaved::Generate(1, seed0, seed1)));
3500*35238bceSAndroid Build Coastguard Worker
3501*35238bceSAndroid Build Coastguard Worker withBarrierGroup->addChild(new InterCallTestCase(
3502*35238bceSAndroid Build Coastguard Worker m_context,
3503*35238bceSAndroid Build Coastguard Worker (std::string(configs[configNdx].namePrefix) + "_multiple_unrelated_write_read_ordered").c_str(),
3504*35238bceSAndroid Build Coastguard Worker (std::string("Two unrelated ") + target + " write-reads").c_str(), configs[configNdx].storage,
3505*35238bceSAndroid Build Coastguard Worker configs[configNdx].flags,
3506*35238bceSAndroid Build Coastguard Worker InterCallOperations()
3507*35238bceSAndroid Build Coastguard Worker << op::WriteData::Generate(1, seed0) << op::WriteData::Generate(2, seed1) << op::Barrier()
3508*35238bceSAndroid Build Coastguard Worker << op::ReadData::Generate(1, seed0) << op::ReadData::Generate(2, seed1)));
3509*35238bceSAndroid Build Coastguard Worker
3510*35238bceSAndroid Build Coastguard Worker withBarrierGroup->addChild(new InterCallTestCase(
3511*35238bceSAndroid Build Coastguard Worker m_context,
3512*35238bceSAndroid Build Coastguard Worker (std::string(configs[configNdx].namePrefix) + "_multiple_unrelated_write_read_non_ordered").c_str(),
3513*35238bceSAndroid Build Coastguard Worker (std::string("Two unrelated ") + target + " write-reads").c_str(), configs[configNdx].storage,
3514*35238bceSAndroid Build Coastguard Worker configs[configNdx].flags,
3515*35238bceSAndroid Build Coastguard Worker InterCallOperations()
3516*35238bceSAndroid Build Coastguard Worker << op::WriteData::Generate(1, seed0) << op::WriteData::Generate(2, seed1) << op::Barrier()
3517*35238bceSAndroid Build Coastguard Worker << op::ReadData::Generate(2, seed1) << op::ReadData::Generate(1, seed0)));
3518*35238bceSAndroid Build Coastguard Worker }
3519*35238bceSAndroid Build Coastguard Worker
3520*35238bceSAndroid Build Coastguard Worker // .without_memory_barrier
3521*35238bceSAndroid Build Coastguard Worker {
3522*35238bceSAndroid Build Coastguard Worker struct InvocationConfig
3523*35238bceSAndroid Build Coastguard Worker {
3524*35238bceSAndroid Build Coastguard Worker const char *name;
3525*35238bceSAndroid Build Coastguard Worker int count;
3526*35238bceSAndroid Build Coastguard Worker };
3527*35238bceSAndroid Build Coastguard Worker
3528*35238bceSAndroid Build Coastguard Worker static const InvocationConfig ssboInvocations[] = {
3529*35238bceSAndroid Build Coastguard Worker {"1k", 1024},
3530*35238bceSAndroid Build Coastguard Worker {"4k", 4096},
3531*35238bceSAndroid Build Coastguard Worker {"32k", 32768},
3532*35238bceSAndroid Build Coastguard Worker };
3533*35238bceSAndroid Build Coastguard Worker static const InvocationConfig imageInvocations[] = {
3534*35238bceSAndroid Build Coastguard Worker {"8x8", 8},
3535*35238bceSAndroid Build Coastguard Worker {"32x32", 32},
3536*35238bceSAndroid Build Coastguard Worker {"128x128", 128},
3537*35238bceSAndroid Build Coastguard Worker };
3538*35238bceSAndroid Build Coastguard Worker static const InvocationConfig counterInvocations[] = {
3539*35238bceSAndroid Build Coastguard Worker {"32", 32},
3540*35238bceSAndroid Build Coastguard Worker {"128", 128},
3541*35238bceSAndroid Build Coastguard Worker {"1k", 1024},
3542*35238bceSAndroid Build Coastguard Worker };
3543*35238bceSAndroid Build Coastguard Worker static const int callCounts[] = {2, 5, 100};
3544*35238bceSAndroid Build Coastguard Worker
3545*35238bceSAndroid Build Coastguard Worker for (int invocationNdx = 0; invocationNdx < DE_LENGTH_OF_ARRAY(ssboInvocations); ++invocationNdx)
3546*35238bceSAndroid Build Coastguard Worker for (int callCountNdx = 0; callCountNdx < DE_LENGTH_OF_ARRAY(callCounts); ++callCountNdx)
3547*35238bceSAndroid Build Coastguard Worker withoutBarrierGroup->addChild(new SSBOConcurrentAtomicCase(
3548*35238bceSAndroid Build Coastguard Worker m_context,
3549*35238bceSAndroid Build Coastguard Worker (std::string("ssbo_atomic_dispatch_") + de::toString(callCounts[callCountNdx]) + "_calls_" +
3550*35238bceSAndroid Build Coastguard Worker ssboInvocations[invocationNdx].name + "_invocations")
3551*35238bceSAndroid Build Coastguard Worker .c_str(),
3552*35238bceSAndroid Build Coastguard Worker "", callCounts[callCountNdx], ssboInvocations[invocationNdx].count));
3553*35238bceSAndroid Build Coastguard Worker
3554*35238bceSAndroid Build Coastguard Worker for (int invocationNdx = 0; invocationNdx < DE_LENGTH_OF_ARRAY(imageInvocations); ++invocationNdx)
3555*35238bceSAndroid Build Coastguard Worker for (int callCountNdx = 0; callCountNdx < DE_LENGTH_OF_ARRAY(callCounts); ++callCountNdx)
3556*35238bceSAndroid Build Coastguard Worker withoutBarrierGroup->addChild(new ConcurrentImageAtomicCase(
3557*35238bceSAndroid Build Coastguard Worker m_context,
3558*35238bceSAndroid Build Coastguard Worker (std::string("image_atomic_dispatch_") + de::toString(callCounts[callCountNdx]) +
3559*35238bceSAndroid Build Coastguard Worker "_calls_" + imageInvocations[invocationNdx].name + "_invocations")
3560*35238bceSAndroid Build Coastguard Worker .c_str(),
3561*35238bceSAndroid Build Coastguard Worker "", callCounts[callCountNdx], imageInvocations[invocationNdx].count));
3562*35238bceSAndroid Build Coastguard Worker
3563*35238bceSAndroid Build Coastguard Worker for (int invocationNdx = 0; invocationNdx < DE_LENGTH_OF_ARRAY(counterInvocations); ++invocationNdx)
3564*35238bceSAndroid Build Coastguard Worker for (int callCountNdx = 0; callCountNdx < DE_LENGTH_OF_ARRAY(callCounts); ++callCountNdx)
3565*35238bceSAndroid Build Coastguard Worker withoutBarrierGroup->addChild(new ConcurrentAtomicCounterCase(
3566*35238bceSAndroid Build Coastguard Worker m_context,
3567*35238bceSAndroid Build Coastguard Worker (std::string("atomic_counter_dispatch_") + de::toString(callCounts[callCountNdx]) +
3568*35238bceSAndroid Build Coastguard Worker "_calls_" + counterInvocations[invocationNdx].name + "_invocations")
3569*35238bceSAndroid Build Coastguard Worker .c_str(),
3570*35238bceSAndroid Build Coastguard Worker "", callCounts[callCountNdx], counterInvocations[invocationNdx].count));
3571*35238bceSAndroid Build Coastguard Worker
3572*35238bceSAndroid Build Coastguard Worker for (int invocationNdx = 0; invocationNdx < DE_LENGTH_OF_ARRAY(counterInvocations); ++invocationNdx)
3573*35238bceSAndroid Build Coastguard Worker for (int callCountNdx = 0; callCountNdx < DE_LENGTH_OF_ARRAY(callCounts); ++callCountNdx)
3574*35238bceSAndroid Build Coastguard Worker withoutBarrierGroup->addChild(new ConcurrentSSBOAtomicCounterMixedCase(
3575*35238bceSAndroid Build Coastguard Worker m_context,
3576*35238bceSAndroid Build Coastguard Worker (std::string("ssbo_atomic_counter_mixed_dispatch_") +
3577*35238bceSAndroid Build Coastguard Worker de::toString(callCounts[callCountNdx]) + "_calls_" +
3578*35238bceSAndroid Build Coastguard Worker counterInvocations[invocationNdx].name + "_invocations")
3579*35238bceSAndroid Build Coastguard Worker .c_str(),
3580*35238bceSAndroid Build Coastguard Worker "", callCounts[callCountNdx], counterInvocations[invocationNdx].count));
3581*35238bceSAndroid Build Coastguard Worker }
3582*35238bceSAndroid Build Coastguard Worker }
3583*35238bceSAndroid Build Coastguard Worker }
3584*35238bceSAndroid Build Coastguard Worker }
3585*35238bceSAndroid Build Coastguard Worker
3586*35238bceSAndroid Build Coastguard Worker } // namespace Functional
3587*35238bceSAndroid Build Coastguard Worker } // namespace gles31
3588*35238bceSAndroid Build Coastguard Worker } // namespace deqp
3589