13c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*------------------------------------------------------------------------- 23c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * drawElements Quality Program OpenGL ES 3.1 Module 33c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * ------------------------------------------------- 43c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 53c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Copyright 2014 The Android Open Source Project 63c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 73c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Licensed under the Apache License, Version 2.0 (the "License"); 83c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * you may not use this file except in compliance with the License. 93c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * You may obtain a copy of the License at 103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * http://www.apache.org/licenses/LICENSE-2.0 123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Unless required by applicable law or agreed to in writing, software 143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * distributed under the License is distributed on an "AS IS" BASIS, 153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * See the License for the specific language governing permissions and 173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * limitations under the License. 183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*! 203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \file 213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Synchronization Tests 223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "es31fSynchronizationTests.hpp" 253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuTestLog.hpp" 263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuSurface.hpp" 273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuRenderTarget.hpp" 283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluRenderContext.hpp" 293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluShaderProgram.hpp" 303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluObjectWrapper.hpp" 313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluPixelTransfer.hpp" 323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluContextInfo.hpp" 333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glwFunctions.hpp" 343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glwEnums.hpp" 353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deStringUtil.hpp" 363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deSharedPtr.hpp" 373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deMemory.h" 383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deRandom.hpp" 393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <map> 413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 423c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace deqp 433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 443c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace gles31 453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 463c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace Functional 473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 483c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace 493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 523c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic bool validateSortedAtomicRampAdditionValueChain (const std::vector<deUint32>& valueChain, deUint32 sumValue, int& invalidOperationNdx, deUint32& errorDelta, deUint32& errorExpected) 533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::vector<deUint32> chainDelta(valueChain.size()); 553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int callNdx = 0; callNdx < (int)valueChain.size(); ++callNdx) 573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry chainDelta[callNdx] = ((callNdx + 1 == (int)valueChain.size()) ? (sumValue) : (valueChain[callNdx+1])) - valueChain[callNdx]; 583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // chainDelta contains now the actual additions applied to the value 603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // check there exists an addition ramp form 1 to ... 613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::sort(chainDelta.begin(), chainDelta.end()); 623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int callNdx = 0; callNdx < (int)valueChain.size(); ++callNdx) 643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if ((int)chainDelta[callNdx] != callNdx+1) 663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry invalidOperationNdx = callNdx; 683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry errorDelta = chainDelta[callNdx]; 693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry errorExpected = callNdx+1; 703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return true; 763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 783c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic void readBuffer (const glw::Functions& gl, deUint32 target, int numElements, std::vector<deUint32>& result) 793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const void* ptr = gl.mapBufferRange(target, 0, (int)(sizeof(deUint32) * numElements), GL_MAP_READ_BIT); 813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "map"); 823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!ptr) 843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw tcu::TestError("mapBufferRange returned NULL"); 853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry result.resize(numElements); 873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry memcpy(&result[0], ptr, sizeof(deUint32) * numElements); 883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (gl.unmapBuffer(target) == GL_FALSE) 903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw tcu::TestError("unmapBuffer returned false"); 913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 933c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic deUint32 readBufferUint32 (const glw::Functions& gl, deUint32 target) 943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::vector<deUint32> vec; 963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry readBuffer(gl, target, 1, vec); 983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return vec[0]; 1003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry//! Generate a ramp of values from 1 to numElements, and shuffle it 1033c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid generateShuffledRamp (int numElements, std::vector<int>& ramp) 1043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry de::Random rng(0xabcd); 1063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // some positive (non-zero) unique values 1083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ramp.resize(numElements); 1093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int callNdx = 0; callNdx < numElements; ++callNdx) 1103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ramp[callNdx] = callNdx + 1; 1113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry rng.shuffle(ramp.begin(), ramp.end()); 1133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1153c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass InterInvocationTestCase : public TestCase 1163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1173c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 1183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry enum StorageType 1193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry STORAGE_BUFFER = 0, 1213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry STORAGE_IMAGE, 1223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry STORAGE_LAST 1243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 1253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry enum CaseFlags 1263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry FLAG_ATOMIC = 0x1, 1283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry FLAG_ALIASING_STORAGES = 0x2, 1293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry FLAG_IN_GROUP = 0x4, 1303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 1313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry InterInvocationTestCase (Context& context, const char* name, const char* desc, StorageType storage, int flags = 0); 1333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ~InterInvocationTestCase (void); 1343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1353c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate: 1363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void init (void); 1373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void deinit (void); 1383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IterateResult iterate (void); 1393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void runCompute (void); 1413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool verifyResults (void); 1423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry virtual std::string genShaderSource (void) const = 0; 1433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1443c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 1453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::string genBarrierSource (void) const; 1463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const StorageType m_storage; 1483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool m_useAtomic; 1493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool m_aliasingStorages; 1503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool m_syncWithGroup; 1513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int m_workWidth; // !< total work width 1523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int m_workHeight; // !< ... height 1533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int m_localWidth; // !< group width 1543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int m_localHeight; // !< group height 1553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int m_elementsPerInvocation; // !< elements accessed by a single invocation 1563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1573c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate: 1583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glw::GLuint m_storageBuf; 1593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glw::GLuint m_storageTex; 1603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glw::GLuint m_resultBuf; 1613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glu::ShaderProgram* m_program; 1623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 1633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1643c827367444ee418f129b2c238299f49d3264554Jarkko PoyryInterInvocationTestCase::InterInvocationTestCase (Context& context, const char* name, const char* desc, StorageType storage, int flags) 1653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : TestCase (context, name, desc) 1663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_storage (storage) 1673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_useAtomic ((flags & FLAG_ATOMIC) != 0) 1683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_aliasingStorages ((flags & FLAG_ALIASING_STORAGES) != 0) 1693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_syncWithGroup ((flags & FLAG_IN_GROUP) != 0) 1703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_workWidth (256) 1713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_workHeight (256) 1723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_localWidth (16) 1733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_localHeight (8) 1743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_elementsPerInvocation (8) 1753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_storageBuf (0) 1763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_storageTex (0) 1773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_resultBuf (0) 1783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_program (DE_NULL) 1793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(m_storage < STORAGE_LAST); 1813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(m_localWidth*m_localHeight <= 128); // minimum MAX_COMPUTE_WORK_GROUP_INVOCATIONS value 1823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1843c827367444ee418f129b2c238299f49d3264554Jarkko PoyryInterInvocationTestCase::~InterInvocationTestCase (void) 1853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deinit(); 1873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1893c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid InterInvocationTestCase::init (void) 1903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // requirements 1943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_useAtomic && m_storage == STORAGE_IMAGE && !m_context.getContextInfo().isExtensionSupported("GL_OES_shader_image_atomic")) 1963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw tcu::NotSupportedError("Test requires GL_OES_shader_image_atomic extension"); 1973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // program 1993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_program = new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources() << glu::ComputeSource(genShaderSource())); 2013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << *m_program; 2023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!m_program->isOk()) 2033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw tcu::TestError("could not build program"); 2043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // source 2063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_storage == STORAGE_BUFFER) 2083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int bufferElements = m_workWidth * m_workHeight * m_elementsPerInvocation; 2103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int bufferSize = bufferElements * sizeof(deUint32); 2113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::vector<deUint32> zeroBuffer (bufferElements, 0); 2123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Allocating zero-filled buffer for storage, size " << bufferElements << " elements, " << bufferSize << " bytes." << tcu::TestLog::EndMessage; 2143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.genBuffers(1, &m_storageBuf); 2163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindBuffer(GL_SHADER_STORAGE_BUFFER, m_storageBuf); 2173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bufferData(GL_SHADER_STORAGE_BUFFER, bufferSize, &zeroBuffer[0], GL_STATIC_DRAW); 2183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "gen storage buf"); 2193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_storage == STORAGE_IMAGE) 2213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int bufferElements = m_workWidth * m_workHeight * m_elementsPerInvocation; 2233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int bufferSize = bufferElements * sizeof(deUint32); 2243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2258852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Allocating image for storage, size " << m_workWidth << "x" << m_workHeight * m_elementsPerInvocation << ", " << bufferSize << " bytes." << tcu::TestLog::EndMessage; 2263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.genTextures(1, &m_storageTex); 2283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindTexture(GL_TEXTURE_2D, m_storageTex); 2298852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry gl.texStorage2D(GL_TEXTURE_2D, 1, GL_R32I, m_workWidth, m_workHeight * m_elementsPerInvocation); 2303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 2313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 2323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "gen storage image"); 2338852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 2348852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry // Zero-fill 2358852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Filling image with 0." << tcu::TestLog::EndMessage; 2368852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 2378852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry { 2388852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const std::vector<deInt32> zeroBuffer(m_workWidth * m_workHeight * m_elementsPerInvocation, 0); 2398852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry gl.texSubImage2D(GL_TEXTURE_2D, 0, 0, 0, m_workWidth, m_workHeight * m_elementsPerInvocation, GL_RED_INTEGER, GL_INT, &zeroBuffer[0]); 2408852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "specify image contents"); 2418852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry } 2423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 2443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(DE_FALSE); 2453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // destination 2473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int bufferElements = m_workWidth * m_workHeight; 2503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int bufferSize = bufferElements * sizeof(deUint32); 2513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::vector<deInt32> negativeBuffer (bufferElements, -1); 2523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Allocating -1 filled buffer for results, size " << bufferElements << " elements, " << bufferSize << " bytes." << tcu::TestLog::EndMessage; 2543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.genBuffers(1, &m_resultBuf); 2563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindBuffer(GL_SHADER_STORAGE_BUFFER, m_resultBuf); 2573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bufferData(GL_SHADER_STORAGE_BUFFER, bufferSize, &negativeBuffer[0], GL_STATIC_DRAW); 2583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "gen storage buf"); 2593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 2613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2623c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid InterInvocationTestCase::deinit (void) 2633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_storageBuf) 2653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_context.getRenderContext().getFunctions().deleteBuffers(1, &m_storageBuf); 2673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_storageBuf = DE_NULL; 2683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_storageTex) 2713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_context.getRenderContext().getFunctions().deleteTextures(1, &m_storageTex); 2733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_storageTex = DE_NULL; 2743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_resultBuf) 2773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_context.getRenderContext().getFunctions().deleteBuffers(1, &m_resultBuf); 2793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_resultBuf = DE_NULL; 2803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry delete m_program; 2833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_program = DE_NULL; 2843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 2853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2863c827367444ee418f129b2c238299f49d3264554Jarkko PoyryInterInvocationTestCase::IterateResult InterInvocationTestCase::iterate (void) 2873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Dispatch 2893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry runCompute(); 2903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Verify buffer contents 2923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (verifyResults()) 2933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 2943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 2953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, (std::string((m_storage == STORAGE_BUFFER) ? ("buffer") : ("image")) + " content verification failed").c_str()); 2963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return STOP; 2983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 2993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3003c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid InterInvocationTestCase::runCompute (void) 3013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 3023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 3033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int groupsX = m_workWidth / m_localWidth; 3043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int groupsY = m_workHeight / m_localHeight; 3053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT((m_workWidth % m_localWidth) == 0); 3073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT((m_workHeight % m_localHeight) == 0); 3083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() 3103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << tcu::TestLog::Message 3113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "Dispatching compute.\n" 3123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " group size: " << m_localWidth << "x" << m_localHeight << "\n" 3133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " dispatch size: " << groupsX << "x" << groupsY << "\n" 3143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " total work size: " << m_workWidth << "x" << m_workHeight << "\n" 3153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << tcu::TestLog::EndMessage; 3163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.useProgram(m_program->getProgram()); 3183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // source 3203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_storage == STORAGE_BUFFER && !m_aliasingStorages) 3213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 3223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_storageBuf); 3233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "bind source buf"); 3243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 3253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_storage == STORAGE_BUFFER && m_aliasingStorages) 3263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 3273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_storageBuf); 3283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, m_storageBuf); 3293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "bind source buf"); 3303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Binding same buffer object to buffer storages." << tcu::TestLog::EndMessage; 3323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 3333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_storage == STORAGE_IMAGE && !m_aliasingStorages) 3343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 3353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindImageTexture(1, m_storageTex, 0, GL_FALSE, 0, GL_READ_WRITE, GL_R32I); 3363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "bind result buf"); 3373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 3383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_storage == STORAGE_IMAGE && m_aliasingStorages) 3393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 3403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindImageTexture(1, m_storageTex, 0, GL_FALSE, 0, GL_READ_WRITE, GL_R32I); 3413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindImageTexture(2, m_storageTex, 0, GL_FALSE, 0, GL_READ_WRITE, GL_R32I); 3423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "bind result buf"); 3443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Binding same texture level to image storages." << tcu::TestLog::EndMessage; 3463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 3473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 3483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(DE_FALSE); 3493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // destination 3513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_resultBuf); 3523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "bind result buf"); 3533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // dispatch 3553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.dispatchCompute(groupsX, groupsY, 1); 3563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "dispatchCompute"); 3573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 3583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3593c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool InterInvocationTestCase::verifyResults (void) 3603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 3613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 3623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int errorFloodThreshold = 5; 3633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int numErrorsLogged = 0; 3643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const void* mapped = DE_NULL; 3653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::vector<deInt32> results (m_workWidth * m_workHeight); 3663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool error = false; 3673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindBuffer(GL_SHADER_STORAGE_BUFFER, m_resultBuf); 3693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry mapped = gl.mapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, m_workWidth * m_workHeight * sizeof(deInt32), GL_MAP_READ_BIT); 3703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "map buffer"); 3713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // copy to properly aligned array 3733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deMemcpy(&results[0], mapped, m_workWidth * m_workHeight * sizeof(deUint32)); 3743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (gl.unmapBuffer(GL_SHADER_STORAGE_BUFFER) != GL_TRUE) 3763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw tcu::TestError("memory map store corrupted"); 3773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // check the results 3793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < (int)results.size(); ++ndx) 3803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 3813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (results[ndx] != 1) 3823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 3833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry error = true; 3843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (numErrorsLogged == 0) 3863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Result buffer failed, got unexpected values.\n" << tcu::TestLog::EndMessage; 3873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (numErrorsLogged++ < errorFloodThreshold) 3883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << " Error at index " << ndx << ": expected 1, got " << results[ndx] << ".\n" << tcu::TestLog::EndMessage; 3893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 3903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 3913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // after N errors, no point continuing verification 3923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << " -- too many errors, skipping verification --\n" << tcu::TestLog::EndMessage; 3933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry break; 3943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 3953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 3963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 3973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!error) 3993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Result buffer ok." << tcu::TestLog::EndMessage; 4003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return !error; 4013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 4023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4033c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::string InterInvocationTestCase::genBarrierSource (void) const 4043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 4053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::ostringstream buf; 4063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_syncWithGroup) 4083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 4093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Wait until all invocations in this work group have their texture/buffer read/write operations complete 4103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // \note We could also use memoryBarrierBuffer() or memoryBarrierImage() in place of groupMemoryBarrier() but 4113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // we only require intra-workgroup synchronization. 4123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "\n" 4133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " groupMemoryBarrier();\n" 4143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " barrier();\n" 4153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "\n"; 4163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 4173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_storage == STORAGE_BUFFER) 4183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 4193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(!m_syncWithGroup); 4203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Waiting only for data written by this invocation. Since all buffer reads and writes are 4223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // processed in order (within a single invocation), we don't have to do anything. 4233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "\n"; 4243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 4253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_storage == STORAGE_IMAGE) 4263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 4273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(!m_syncWithGroup); 4283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Waiting only for data written by this invocation. But since operations complete in undefined 4303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // order, we have to wait for them to complete. 4313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "\n" 4323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " memoryBarrierImage();\n" 4333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "\n"; 4343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 4353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 4363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(DE_FALSE); 4373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return buf.str(); 4393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 4403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4413c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass InvocationBasicCase : public InterInvocationTestCase 4423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 4433c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 4443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry InvocationBasicCase (Context& context, const char* name, const char* desc, StorageType storage, int flags); 4453c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate: 4463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::string genShaderSource (void) const; 4473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry virtual std::string genShaderMainBlock (void) const = 0; 4483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 4493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4503c827367444ee418f129b2c238299f49d3264554Jarkko PoyryInvocationBasicCase::InvocationBasicCase (Context& context, const char* name, const char* desc, StorageType storage, int flags) 4513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : InterInvocationTestCase(context, name, desc, storage, flags) 4523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 4533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 4543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4553c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::string InvocationBasicCase::genShaderSource (void) const 4563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 4573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool useImageAtomics = m_useAtomic && m_storage == STORAGE_IMAGE; 4583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::ostringstream buf; 4593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "#version 310 es\n" 4613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << ((useImageAtomics) ? ("#extension GL_OES_shader_image_atomic : require\n") : ("")) 4623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "layout (local_size_x=" << m_localWidth << ", local_size_y=" << m_localHeight << ") in;\n" 4633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "layout(binding=0, std430) buffer Output\n" 4643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "{\n" 4653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " highp int values[];\n" 4663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "} sb_result;\n"; 4673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_storage == STORAGE_BUFFER) 4693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "layout(binding=1, std430) coherent buffer Storage\n" 4703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "{\n" 4713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " highp int values[];\n" 4723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "} sb_store;\n" 4733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "\n" 4743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "highp int getIndex (in highp uvec2 localID, in highp int element)\n" 4753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "{\n" 4763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " highp uint groupNdx = gl_NumWorkGroups.x * gl_WorkGroupID.y + gl_WorkGroupID.x;\n" 4773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " return int((localID.y * gl_NumWorkGroups.x * gl_NumWorkGroups.y * gl_WorkGroupSize.x) + (groupNdx * gl_WorkGroupSize.x) + localID.x) * " << m_elementsPerInvocation << " + element;\n" 4783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "}\n"; 4793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_storage == STORAGE_IMAGE) 4803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "layout(r32i, binding=1) coherent uniform highp iimage2D u_image;\n" 4813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "\n" 4823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "highp ivec2 getCoord (in highp uvec2 localID, in highp int element)\n" 4833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "{\n" 4843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " return ivec2(int(gl_WorkGroupID.x * gl_WorkGroupSize.x + localID.x), int(gl_WorkGroupID.y * gl_WorkGroupSize.y + localID.y) + element * " << m_workHeight << ");\n" 4853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "}\n"; 4863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 4873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(DE_FALSE); 4883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "\n" 4903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "void main (void)\n" 4913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "{\n" 4923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " int resultNdx = int(gl_GlobalInvocationID.y * gl_NumWorkGroups.x * gl_WorkGroupSize.x + gl_GlobalInvocationID.x);\n" 4933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " int groupNdx = int(gl_NumWorkGroups.x * gl_WorkGroupID.y + gl_WorkGroupID.x);\n" 4943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " bool allOk = true;\n" 4953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "\n" 4963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << genShaderMainBlock() 4973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "\n" 4983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " sb_result.values[resultNdx] = (allOk) ? (1) : (0);\n" 4993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "}\n"; 5003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return buf.str(); 5023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 5033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5043c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass InvocationWriteReadCase : public InvocationBasicCase 5053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 5063c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 5073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry InvocationWriteReadCase (Context& context, const char* name, const char* desc, StorageType storage, int flags); 5083c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate: 5093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::string genShaderMainBlock (void) const; 5103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 5113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5123c827367444ee418f129b2c238299f49d3264554Jarkko PoyryInvocationWriteReadCase::InvocationWriteReadCase (Context& context, const char* name, const char* desc, StorageType storage, int flags) 5133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : InvocationBasicCase(context, name, desc, storage, flags) 5143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 5153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 5163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5173c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::string InvocationWriteReadCase::genShaderMainBlock (void) const 5183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 5193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::ostringstream buf; 5203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // write 5223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < m_elementsPerInvocation; ++ndx) 5243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 5253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_storage == STORAGE_BUFFER && m_useAtomic) 5263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "\tatomicAdd(sb_store.values[getIndex(gl_LocalInvocationID.xy, " << ndx << ")], groupNdx);\n"; 5273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_storage == STORAGE_BUFFER && !m_useAtomic) 5283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "\tsb_store.values[getIndex(gl_LocalInvocationID.xy, " << ndx << ")] = groupNdx;\n"; 5293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_storage == STORAGE_IMAGE && m_useAtomic) 5303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "\timageAtomicAdd(u_image, getCoord(gl_LocalInvocationID.xy, " << ndx << "), int(groupNdx));\n"; 5313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_storage == STORAGE_IMAGE && !m_useAtomic) 5323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "\timageStore(u_image, getCoord(gl_LocalInvocationID.xy, " << ndx << "), ivec4(int(groupNdx), 0, 0, 0));\n"; 5333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 5343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(DE_FALSE); 5353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 5363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // barrier 5383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << genBarrierSource(); 5403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // read 5423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < m_elementsPerInvocation; ++ndx) 5443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 5453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const std::string localID = (m_syncWithGroup) ? ("(gl_LocalInvocationID.xy + uvec2(" + de::toString(ndx+1) + ", " + de::toString(2*ndx) + ")) % gl_WorkGroupSize.xy") : ("gl_LocalInvocationID.xy"); 5463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_storage == STORAGE_BUFFER && m_useAtomic) 5483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "\tallOk = allOk && (atomicExchange(sb_store.values[getIndex(" << localID << ", " << ndx << ")], 0) == groupNdx);\n"; 5493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_storage == STORAGE_BUFFER && !m_useAtomic) 5503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "\tallOk = allOk && (sb_store.values[getIndex(" << localID << ", " << ndx << ")] == groupNdx);\n"; 5513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_storage == STORAGE_IMAGE && m_useAtomic) 5523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "\tallOk = allOk && (imageAtomicExchange(u_image, getCoord(" << localID << ", " << ndx << "), 0) == groupNdx);\n"; 5533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_storage == STORAGE_IMAGE && !m_useAtomic) 5543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "\tallOk = allOk && (imageLoad(u_image, getCoord(" << localID << ", " << ndx << ")).x == groupNdx);\n"; 5553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 5563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(DE_FALSE); 5573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 5583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return buf.str(); 5603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 5613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5623c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass InvocationReadWriteCase : public InvocationBasicCase 5633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 5643c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 5653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry InvocationReadWriteCase (Context& context, const char* name, const char* desc, StorageType storage, int flags); 5663c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate: 5673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::string genShaderMainBlock (void) const; 5683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 5693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5703c827367444ee418f129b2c238299f49d3264554Jarkko PoyryInvocationReadWriteCase::InvocationReadWriteCase (Context& context, const char* name, const char* desc, StorageType storage, int flags) 5713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : InvocationBasicCase(context, name, desc, storage, flags) 5723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 5733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 5743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5753c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::string InvocationReadWriteCase::genShaderMainBlock (void) const 5763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 5773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::ostringstream buf; 5783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // read 5803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < m_elementsPerInvocation; ++ndx) 5823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 5833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const std::string localID = (m_syncWithGroup) ? ("(gl_LocalInvocationID.xy + uvec2(" + de::toString(ndx+1) + ", " + de::toString(2*ndx) + ")) % gl_WorkGroupSize.xy") : ("gl_LocalInvocationID.xy"); 5843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_storage == STORAGE_BUFFER && m_useAtomic) 5863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "\tallOk = allOk && (atomicExchange(sb_store.values[getIndex(" << localID << ", " << ndx << ")], 123) == 0);\n"; 5873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_storage == STORAGE_BUFFER && !m_useAtomic) 5883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "\tallOk = allOk && (sb_store.values[getIndex(" << localID << ", " << ndx << ")] == 0);\n"; 5893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_storage == STORAGE_IMAGE && m_useAtomic) 5903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "\tallOk = allOk && (imageAtomicExchange(u_image, getCoord(" << localID << ", " << ndx << "), 123) == 0);\n"; 5913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_storage == STORAGE_IMAGE && !m_useAtomic) 5923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "\tallOk = allOk && (imageLoad(u_image, getCoord(" << localID << ", " << ndx << ")).x == 0);\n"; 5933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 5943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(DE_FALSE); 5953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 5963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // barrier 5983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << genBarrierSource(); 6003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // write 6023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < m_elementsPerInvocation; ++ndx) 6043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 6053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_storage == STORAGE_BUFFER && m_useAtomic) 6063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "\tatomicAdd(sb_store.values[getIndex(gl_LocalInvocationID.xy, " << ndx << ")], groupNdx);\n"; 6073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_storage == STORAGE_BUFFER && !m_useAtomic) 6083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "\tsb_store.values[getIndex(gl_LocalInvocationID.xy, " << ndx << ")] = groupNdx;\n"; 6093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_storage == STORAGE_IMAGE && m_useAtomic) 6103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "\timageAtomicAdd(u_image, getCoord(gl_LocalInvocationID.xy, " << ndx << "), int(groupNdx));\n"; 6113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_storage == STORAGE_IMAGE && !m_useAtomic) 6123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "\timageStore(u_image, getCoord(gl_LocalInvocationID.xy, " << ndx << "), ivec4(int(groupNdx), 0, 0, 0));\n"; 6133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 6143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(DE_FALSE); 6153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 6163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return buf.str(); 6183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 6193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6203c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass InvocationOverWriteCase : public InvocationBasicCase 6213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 6223c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 6233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry InvocationOverWriteCase (Context& context, const char* name, const char* desc, StorageType storage, int flags); 6243c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate: 6253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::string genShaderMainBlock (void) const; 6263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 6273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6283c827367444ee418f129b2c238299f49d3264554Jarkko PoyryInvocationOverWriteCase::InvocationOverWriteCase (Context& context, const char* name, const char* desc, StorageType storage, int flags) 6293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : InvocationBasicCase(context, name, desc, storage, flags) 6303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 6313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 6323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6333c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::string InvocationOverWriteCase::genShaderMainBlock (void) const 6343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 6353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::ostringstream buf; 6363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // write 6383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < m_elementsPerInvocation; ++ndx) 6403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 6413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_storage == STORAGE_BUFFER && m_useAtomic) 6423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "\tatomicAdd(sb_store.values[getIndex(gl_LocalInvocationID.xy, " << ndx << ")], 456);\n"; 6433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_storage == STORAGE_BUFFER && !m_useAtomic) 6443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "\tsb_store.values[getIndex(gl_LocalInvocationID.xy, " << ndx << ")] = 456;\n"; 6453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_storage == STORAGE_IMAGE && m_useAtomic) 6463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "\timageAtomicAdd(u_image, getCoord(gl_LocalInvocationID.xy, " << ndx << "), 456);\n"; 6473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_storage == STORAGE_IMAGE && !m_useAtomic) 6483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "\timageStore(u_image, getCoord(gl_LocalInvocationID.xy, " << ndx << "), ivec4(456, 0, 0, 0));\n"; 6493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 6503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(DE_FALSE); 6513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 6523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // barrier 6543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << genBarrierSource(); 6563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // write over 6583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < m_elementsPerInvocation; ++ndx) 6603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 6613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // write another invocation's value or our own value depending on test type 6623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const std::string localID = (m_syncWithGroup) ? ("(gl_LocalInvocationID.xy + uvec2(" + de::toString(ndx+4) + ", " + de::toString(3*ndx) + ")) % gl_WorkGroupSize.xy") : ("gl_LocalInvocationID.xy"); 6633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_storage == STORAGE_BUFFER && m_useAtomic) 6653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "\tatomicExchange(sb_store.values[getIndex(" << localID << ", " << ndx << ")], groupNdx);\n"; 6663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_storage == STORAGE_BUFFER && !m_useAtomic) 6673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "\tsb_store.values[getIndex(" << localID << ", " << ndx << ")] = groupNdx;\n"; 6683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_storage == STORAGE_IMAGE && m_useAtomic) 6693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "\timageAtomicExchange(u_image, getCoord(" << localID << ", " << ndx << "), groupNdx);\n"; 6703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_storage == STORAGE_IMAGE && !m_useAtomic) 6713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "\timageStore(u_image, getCoord(" << localID << ", " << ndx << "), ivec4(groupNdx, 0, 0, 0));\n"; 6723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 6733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(DE_FALSE); 6743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 6753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // barrier 6773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << genBarrierSource(); 6793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // read 6813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < m_elementsPerInvocation; ++ndx) 6833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 6843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // check another invocation's value or our own value depending on test type 6853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const std::string localID = (m_syncWithGroup) ? ("(gl_LocalInvocationID.xy + uvec2(" + de::toString(ndx+1) + ", " + de::toString(2*ndx) + ")) % gl_WorkGroupSize.xy") : ("gl_LocalInvocationID.xy"); 6863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_storage == STORAGE_BUFFER && m_useAtomic) 6883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "\tallOk = allOk && (atomicExchange(sb_store.values[getIndex(" << localID << ", " << ndx << ")], 123) == groupNdx);\n"; 6893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_storage == STORAGE_BUFFER && !m_useAtomic) 6903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "\tallOk = allOk && (sb_store.values[getIndex(" << localID << ", " << ndx << ")] == groupNdx);\n"; 6913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_storage == STORAGE_IMAGE && m_useAtomic) 6923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "\tallOk = allOk && (imageAtomicExchange(u_image, getCoord(" << localID << ", " << ndx << "), 123) == groupNdx);\n"; 6933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_storage == STORAGE_IMAGE && !m_useAtomic) 6943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "\tallOk = allOk && (imageLoad(u_image, getCoord(" << localID << ", " << ndx << ")).x == groupNdx);\n"; 6953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 6963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(DE_FALSE); 6973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 6983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return buf.str(); 7003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 7013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7023c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass InvocationAliasWriteCase : public InterInvocationTestCase 7033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 7043c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 7053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry enum TestType 7063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 7073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TYPE_WRITE = 0, 7083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TYPE_OVERWRITE, 7093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TYPE_LAST 7113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 7123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry InvocationAliasWriteCase (Context& context, const char* name, const char* desc, TestType type, StorageType storage, int flags); 7143c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate: 7153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::string genShaderSource (void) const; 7163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const TestType m_type; 7183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 7193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7203c827367444ee418f129b2c238299f49d3264554Jarkko PoyryInvocationAliasWriteCase::InvocationAliasWriteCase (Context& context, const char* name, const char* desc, TestType type, StorageType storage, int flags) 7213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : InterInvocationTestCase (context, name, desc, storage, flags | FLAG_ALIASING_STORAGES) 7223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_type (type) 7233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 7243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(type < TYPE_LAST); 7253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 7263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7273c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::string InvocationAliasWriteCase::genShaderSource (void) const 7283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 7293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool useImageAtomics = m_useAtomic && m_storage == STORAGE_IMAGE; 7303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::ostringstream buf; 7313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "#version 310 es\n" 7333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << ((useImageAtomics) ? ("#extension GL_OES_shader_image_atomic : require\n") : ("")) 7343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "layout (local_size_x=" << m_localWidth << ", local_size_y=" << m_localHeight << ") in;\n" 7353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "layout(binding=0, std430) buffer Output\n" 7363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "{\n" 7373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " highp int values[];\n" 7383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "} sb_result;\n"; 7393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_storage == STORAGE_BUFFER) 7413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "layout(binding=1, std430) coherent buffer Storage0\n" 7423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "{\n" 7433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " highp int values[];\n" 7443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "} sb_store0;\n" 7453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "layout(binding=2, std430) coherent buffer Storage1\n" 7463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "{\n" 7473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " highp int values[];\n" 7483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "} sb_store1;\n" 7493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "\n" 7503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "highp int getIndex (in highp uvec2 localID, in highp int element)\n" 7513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "{\n" 7523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " highp uint groupNdx = gl_NumWorkGroups.x * gl_WorkGroupID.y + gl_WorkGroupID.x;\n" 7533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " return int((localID.y * gl_NumWorkGroups.x * gl_NumWorkGroups.y * gl_WorkGroupSize.x) + (groupNdx * gl_WorkGroupSize.x) + localID.x) * " << m_elementsPerInvocation << " + element;\n" 7543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "}\n"; 7553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_storage == STORAGE_IMAGE) 7563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "layout(r32i, binding=1) coherent uniform highp iimage2D u_image0;\n" 7573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "layout(r32i, binding=2) coherent uniform highp iimage2D u_image1;\n" 7583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "\n" 7593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "highp ivec2 getCoord (in highp uvec2 localID, in highp int element)\n" 7603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "{\n" 7613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " return ivec2(int(gl_WorkGroupID.x * gl_WorkGroupSize.x + localID.x), int(gl_WorkGroupID.y * gl_WorkGroupSize.y + localID.y) + element * " << m_workHeight << ");\n" 7623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "}\n"; 7633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 7643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(DE_FALSE); 7653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "\n" 7673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "void main (void)\n" 7683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "{\n" 7693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " int resultNdx = int(gl_GlobalInvocationID.y * gl_NumWorkGroups.x * gl_WorkGroupSize.x + gl_GlobalInvocationID.x);\n" 7703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " int groupNdx = int(gl_NumWorkGroups.x * gl_WorkGroupID.y + gl_WorkGroupID.x);\n" 7713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " bool allOk = true;\n" 7723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "\n"; 7733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_type == TYPE_OVERWRITE) 7753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 7763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // write 7773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < m_elementsPerInvocation; ++ndx) 7793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 7803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_storage == STORAGE_BUFFER && m_useAtomic) 7813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "\tatomicAdd(sb_store0.values[getIndex(gl_LocalInvocationID.xy, " << ndx << ")], 456);\n"; 7823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_storage == STORAGE_BUFFER && !m_useAtomic) 7833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "\tsb_store0.values[getIndex(gl_LocalInvocationID.xy, " << ndx << ")] = 456;\n"; 7843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_storage == STORAGE_IMAGE && m_useAtomic) 7853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "\timageAtomicAdd(u_image0, getCoord(gl_LocalInvocationID.xy, " << ndx << "), 456);\n"; 7863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_storage == STORAGE_IMAGE && !m_useAtomic) 7873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "\timageStore(u_image0, getCoord(gl_LocalInvocationID.xy, " << ndx << "), ivec4(456, 0, 0, 0));\n"; 7883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 7893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(DE_FALSE); 7903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 7913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // barrier 7933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << genBarrierSource(); 7953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 7963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 7973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(m_type == TYPE_WRITE); 7983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // write (again) 8003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < m_elementsPerInvocation; ++ndx) 8023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 8033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const std::string localID = (m_syncWithGroup) ? ("(gl_LocalInvocationID.xy + uvec2(" + de::toString(ndx+2) + ", " + de::toString(2*ndx) + ")) % gl_WorkGroupSize.xy") : ("gl_LocalInvocationID.xy"); 8043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_storage == STORAGE_BUFFER && m_useAtomic) 8063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "\tatomicExchange(sb_store1.values[getIndex(" << localID << ", " << ndx << ")], groupNdx);\n"; 8073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_storage == STORAGE_BUFFER && !m_useAtomic) 8083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "\tsb_store1.values[getIndex(" << localID << ", " << ndx << ")] = groupNdx;\n"; 8093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_storage == STORAGE_IMAGE && m_useAtomic) 8103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "\timageAtomicExchange(u_image1, getCoord(" << localID << ", " << ndx << "), groupNdx);\n"; 8113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_storage == STORAGE_IMAGE && !m_useAtomic) 8123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "\timageStore(u_image1, getCoord(" << localID << ", " << ndx << "), ivec4(groupNdx, 0, 0, 0));\n"; 8133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 8143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(DE_FALSE); 8153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 8163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // barrier 8183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << genBarrierSource(); 8203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // read 8223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < m_elementsPerInvocation; ++ndx) 8243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 8253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_storage == STORAGE_BUFFER && m_useAtomic) 8263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "\tallOk = allOk && (atomicExchange(sb_store0.values[getIndex(gl_LocalInvocationID.xy, " << ndx << ")], 123) == groupNdx);\n"; 8273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_storage == STORAGE_BUFFER && !m_useAtomic) 8283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "\tallOk = allOk && (sb_store0.values[getIndex(gl_LocalInvocationID.xy, " << ndx << ")] == groupNdx);\n"; 8293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_storage == STORAGE_IMAGE && m_useAtomic) 8303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "\tallOk = allOk && (imageAtomicExchange(u_image0, getCoord(gl_LocalInvocationID.xy, " << ndx << "), 123) == groupNdx);\n"; 8313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_storage == STORAGE_IMAGE && !m_useAtomic) 8323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "\tallOk = allOk && (imageLoad(u_image0, getCoord(gl_LocalInvocationID.xy, " << ndx << ")).x == groupNdx);\n"; 8333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 8343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(DE_FALSE); 8353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 8363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // return result 8383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "\n" 8403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " sb_result.values[resultNdx] = (allOk) ? (1) : (0);\n" 8413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "}\n"; 8423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return buf.str(); 8443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 8453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8463c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace op 8473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 8483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8493c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct WriteData 8503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 8513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int targetHandle; 8523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int seed; 8533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static WriteData Generate(int targetHandle, int seed) 8553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 8563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry WriteData retVal; 8573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry retVal.targetHandle = targetHandle; 8593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry retVal.seed = seed; 8603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return retVal; 8623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 8633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 8643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8653c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct ReadData 8663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 8673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int targetHandle; 8683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int seed; 8693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static ReadData Generate(int targetHandle, int seed) 8713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 8723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ReadData retVal; 8733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry retVal.targetHandle = targetHandle; 8753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry retVal.seed = seed; 8763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return retVal; 8783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 8793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 8803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8813c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct Barrier 8823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 8833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 8843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8853c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct WriteDataInterleaved 8863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 8873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int targetHandle; 8883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int seed; 8893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool evenOdd; 8903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static WriteDataInterleaved Generate(int targetHandle, int seed, bool evenOdd) 8923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 8933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry WriteDataInterleaved retVal; 8943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry retVal.targetHandle = targetHandle; 8963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry retVal.seed = seed; 8973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry retVal.evenOdd = evenOdd; 8983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return retVal; 9003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 9013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 9023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9033c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct ReadDataInterleaved 9043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 9053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int targetHandle; 9063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int seed0; 9073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int seed1; 9083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static ReadDataInterleaved Generate(int targetHandle, int seed0, int seed1) 9103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 9113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ReadDataInterleaved retVal; 9123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry retVal.targetHandle = targetHandle; 9143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry retVal.seed0 = seed0; 9153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry retVal.seed1 = seed1; 9163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return retVal; 9183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 9193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 9203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9213c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct ReadMultipleData 9223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 9233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int targetHandle0; 9243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int seed0; 9253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int targetHandle1; 9263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int seed1; 9273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static ReadMultipleData Generate(int targetHandle0, int seed0, int targetHandle1, int seed1) 9293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 9303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ReadMultipleData retVal; 9313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry retVal.targetHandle0 = targetHandle0; 9333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry retVal.seed0 = seed0; 9343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry retVal.targetHandle1 = targetHandle1; 9353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry retVal.seed1 = seed1; 9363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return retVal; 9383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 9393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 9403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9413c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct ReadZeroData 9423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 9433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int targetHandle; 9443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static ReadZeroData Generate(int targetHandle) 9463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 9473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ReadZeroData retVal; 9483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry retVal.targetHandle = targetHandle; 9503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return retVal; 9523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 9533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 9543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // namespace op 9563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9573c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass InterCallTestCase; 9583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9593c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass InterCallOperations 9603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 9613c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 9623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry InterCallOperations& operator<< (const op::WriteData&); 9633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry InterCallOperations& operator<< (const op::ReadData&); 9643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry InterCallOperations& operator<< (const op::Barrier&); 9653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry InterCallOperations& operator<< (const op::ReadMultipleData&); 9663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry InterCallOperations& operator<< (const op::WriteDataInterleaved&); 9673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry InterCallOperations& operator<< (const op::ReadDataInterleaved&); 9683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry InterCallOperations& operator<< (const op::ReadZeroData&); 9693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9703c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate: 9713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry struct Command 9723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 9733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry enum CommandType 9743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 9753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TYPE_WRITE = 0, 9763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TYPE_READ, 9773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TYPE_BARRIER, 9783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TYPE_READ_MULTIPLE, 9793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TYPE_WRITE_INTERLEAVE, 9803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TYPE_READ_INTERLEAVE, 9813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TYPE_READ_ZERO, 9823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TYPE_LAST 9843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 9853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry CommandType type; 9873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry union CommandUnion 9893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 9903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry op::WriteData write; 9913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry op::ReadData read; 9923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry op::Barrier barrier; 9933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry op::ReadMultipleData readMulti; 9943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry op::WriteDataInterleaved writeInterleave; 9953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry op::ReadDataInterleaved readInterleave; 9963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry op::ReadZeroData readZero; 9973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } u_cmd; 9983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 9993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry friend class InterCallTestCase; 10013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::vector<Command> m_cmds; 10033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 10043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10053c827367444ee418f129b2c238299f49d3264554Jarkko PoyryInterCallOperations& InterCallOperations::operator<< (const op::WriteData& cmd) 10063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 10073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_cmds.push_back(Command()); 10083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_cmds.back().type = Command::TYPE_WRITE; 10093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_cmds.back().u_cmd.write = cmd; 10103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return *this; 10123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 10133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10143c827367444ee418f129b2c238299f49d3264554Jarkko PoyryInterCallOperations& InterCallOperations::operator<< (const op::ReadData& cmd) 10153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 10163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_cmds.push_back(Command()); 10173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_cmds.back().type = Command::TYPE_READ; 10183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_cmds.back().u_cmd.read = cmd; 10193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return *this; 10213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 10223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10233c827367444ee418f129b2c238299f49d3264554Jarkko PoyryInterCallOperations& InterCallOperations::operator<< (const op::Barrier& cmd) 10243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 10253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_cmds.push_back(Command()); 10263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_cmds.back().type = Command::TYPE_BARRIER; 10273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_cmds.back().u_cmd.barrier = cmd; 10283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return *this; 10303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 10313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10323c827367444ee418f129b2c238299f49d3264554Jarkko PoyryInterCallOperations& InterCallOperations::operator<< (const op::ReadMultipleData& cmd) 10333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 10343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_cmds.push_back(Command()); 10353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_cmds.back().type = Command::TYPE_READ_MULTIPLE; 10363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_cmds.back().u_cmd.readMulti = cmd; 10373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return *this; 10393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 10403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10413c827367444ee418f129b2c238299f49d3264554Jarkko PoyryInterCallOperations& InterCallOperations::operator<< (const op::WriteDataInterleaved& cmd) 10423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 10433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_cmds.push_back(Command()); 10443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_cmds.back().type = Command::TYPE_WRITE_INTERLEAVE; 10453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_cmds.back().u_cmd.writeInterleave = cmd; 10463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return *this; 10483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 10493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10503c827367444ee418f129b2c238299f49d3264554Jarkko PoyryInterCallOperations& InterCallOperations::operator<< (const op::ReadDataInterleaved& cmd) 10513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 10523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_cmds.push_back(Command()); 10533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_cmds.back().type = Command::TYPE_READ_INTERLEAVE; 10543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_cmds.back().u_cmd.readInterleave = cmd; 10553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return *this; 10573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 10583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10593c827367444ee418f129b2c238299f49d3264554Jarkko PoyryInterCallOperations& InterCallOperations::operator<< (const op::ReadZeroData& cmd) 10603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 10613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_cmds.push_back(Command()); 10623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_cmds.back().type = Command::TYPE_READ_ZERO; 10633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_cmds.back().u_cmd.readZero = cmd; 10643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return *this; 10663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 10673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10683c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass InterCallTestCase : public TestCase 10693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 10703c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 10713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry enum StorageType 10723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 10733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry STORAGE_BUFFER = 0, 10743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry STORAGE_IMAGE, 10753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry STORAGE_LAST 10773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 10783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry enum Flags 10793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 10803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry FLAG_USE_ATOMIC = 1, 10813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry FLAG_USE_INT = 2, 10823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 10833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry InterCallTestCase (Context& context, const char* name, const char* desc, StorageType storage, int flags, const InterCallOperations& ops); 10843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ~InterCallTestCase (void); 10853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10863c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate: 10873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void init (void); 10883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void deinit (void); 10893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IterateResult iterate (void); 10903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool verifyResults (void); 10913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void runCommand (const op::WriteData& cmd, int stepNdx, int& programFriendlyName); 10933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void runCommand (const op::ReadData& cmd, int stepNdx, int& programFriendlyName, int& resultStorageFriendlyName); 10943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void runCommand (const op::Barrier&); 10953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void runCommand (const op::ReadMultipleData& cmd, int stepNdx, int& programFriendlyName, int& resultStorageFriendlyName); 10963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void runCommand (const op::WriteDataInterleaved& cmd, int stepNdx, int& programFriendlyName); 10973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void runCommand (const op::ReadDataInterleaved& cmd, int stepNdx, int& programFriendlyName, int& resultStorageFriendlyName); 10983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void runCommand (const op::ReadZeroData& cmd, int stepNdx, int& programFriendlyName, int& resultStorageFriendlyName); 10993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void runSingleRead (int targetHandle, int stepNdx, int& programFriendlyName, int& resultStorageFriendlyName); 11003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glw::GLuint genStorage (int friendlyName); 11023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glw::GLuint genResultStorage (void); 11033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glu::ShaderProgram* genWriteProgram (int seed); 11043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glu::ShaderProgram* genReadProgram (int seed); 11053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glu::ShaderProgram* genReadMultipleProgram (int seed0, int seed1); 11063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glu::ShaderProgram* genWriteInterleavedProgram (int seed, bool evenOdd); 11073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glu::ShaderProgram* genReadInterleavedProgram (int seed0, int seed1); 11083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glu::ShaderProgram* genReadZeroProgram (void); 11093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const StorageType m_storage; 11113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int m_invocationGridSize; // !< width and height of the two dimensional work dispatch 11123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int m_perInvocationSize; // !< number of elements accessed in single invocation 11133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const std::vector<InterCallOperations::Command> m_cmds; 11143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool m_useAtomic; 11153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool m_formatInteger; 11163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::vector<glu::ShaderProgram*> m_operationPrograms; 11183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::vector<glw::GLuint> m_operationResultStorages; 11193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::map<int, glw::GLuint> m_storageIDs; 11203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 11213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11223c827367444ee418f129b2c238299f49d3264554Jarkko PoyryInterCallTestCase::InterCallTestCase (Context& context, const char* name, const char* desc, StorageType storage, int flags, const InterCallOperations& ops) 11233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : TestCase (context, name, desc) 11243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_storage (storage) 11253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_invocationGridSize (512) 11263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_perInvocationSize (2) 11273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_cmds (ops.m_cmds) 11283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_useAtomic ((flags & FLAG_USE_ATOMIC) != 0) 11293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_formatInteger ((flags & FLAG_USE_INT) != 0) 11303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 11313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 11323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11333c827367444ee418f129b2c238299f49d3264554Jarkko PoyryInterCallTestCase::~InterCallTestCase (void) 11343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 11353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deinit(); 11363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 11373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11383c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid InterCallTestCase::init (void) 11393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 11403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int programFriendlyName = 0; 11413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // requirements 11433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_useAtomic && m_storage == STORAGE_IMAGE && !m_context.getContextInfo().isExtensionSupported("GL_OES_shader_image_atomic")) 11453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw tcu::NotSupportedError("Test requires GL_OES_shader_image_atomic extension"); 11463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // generate resources and validate command list 11483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_operationPrograms.resize(m_cmds.size(), DE_NULL); 11503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_operationResultStorages.resize(m_cmds.size(), 0); 11513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int step = 0; step < (int)m_cmds.size(); ++step) 11533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 11543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry switch (m_cmds[step].type) 11553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 11563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case InterCallOperations::Command::TYPE_WRITE: 11573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 11583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const op::WriteData& cmd = m_cmds[step].u_cmd.write; 11593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // new storage handle? 11613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_storageIDs.find(cmd.targetHandle) == m_storageIDs.end()) 11623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_storageIDs[cmd.targetHandle] = genStorage(cmd.targetHandle); 11633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // program 11653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 11663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glu::ShaderProgram* program = genWriteProgram(cmd.seed); 11673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Program #" << ++programFriendlyName << tcu::TestLog::EndMessage; 11693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << *program; 11703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!program->isOk()) 11723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw tcu::TestError("could not build program"); 11733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_operationPrograms[step] = program; 11753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 11763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry break; 11773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 11783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case InterCallOperations::Command::TYPE_READ: 11803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 11813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const op::ReadData& cmd = m_cmds[step].u_cmd.read; 11823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(m_storageIDs.find(cmd.targetHandle) != m_storageIDs.end()); 11833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // program and result storage 11853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 11863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glu::ShaderProgram* program = genReadProgram(cmd.seed); 11873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Program #" << ++programFriendlyName << tcu::TestLog::EndMessage; 11893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << *program; 11903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!program->isOk()) 11923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw tcu::TestError("could not build program"); 11933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_operationPrograms[step] = program; 11953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_operationResultStorages[step] = genResultStorage(); 11963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 11973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry break; 11983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 11993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case InterCallOperations::Command::TYPE_BARRIER: 12013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 12023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry break; 12033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 12043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case InterCallOperations::Command::TYPE_READ_MULTIPLE: 12063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 12073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const op::ReadMultipleData& cmd = m_cmds[step].u_cmd.readMulti; 12083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(m_storageIDs.find(cmd.targetHandle0) != m_storageIDs.end()); 12093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(m_storageIDs.find(cmd.targetHandle1) != m_storageIDs.end()); 12103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // program 12123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 12133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glu::ShaderProgram* program = genReadMultipleProgram(cmd.seed0, cmd.seed1); 12143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Program #" << ++programFriendlyName << tcu::TestLog::EndMessage; 12163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << *program; 12173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!program->isOk()) 12193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw tcu::TestError("could not build program"); 12203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_operationPrograms[step] = program; 12223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_operationResultStorages[step] = genResultStorage(); 12233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 12243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry break; 12253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 12263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case InterCallOperations::Command::TYPE_WRITE_INTERLEAVE: 12283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 12293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const op::WriteDataInterleaved& cmd = m_cmds[step].u_cmd.writeInterleave; 12303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // new storage handle? 12323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_storageIDs.find(cmd.targetHandle) == m_storageIDs.end()) 12333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_storageIDs[cmd.targetHandle] = genStorage(cmd.targetHandle); 12343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // program 12363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 12373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glu::ShaderProgram* program = genWriteInterleavedProgram(cmd.seed, cmd.evenOdd); 12383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Program #" << ++programFriendlyName << tcu::TestLog::EndMessage; 12403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << *program; 12413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!program->isOk()) 12433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw tcu::TestError("could not build program"); 12443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_operationPrograms[step] = program; 12463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 12473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry break; 12483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 12493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case InterCallOperations::Command::TYPE_READ_INTERLEAVE: 12513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 12523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const op::ReadDataInterleaved& cmd = m_cmds[step].u_cmd.readInterleave; 12533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(m_storageIDs.find(cmd.targetHandle) != m_storageIDs.end()); 12543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // program 12563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 12573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glu::ShaderProgram* program = genReadInterleavedProgram(cmd.seed0, cmd.seed1); 12583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Program #" << ++programFriendlyName << tcu::TestLog::EndMessage; 12603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << *program; 12613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!program->isOk()) 12633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw tcu::TestError("could not build program"); 12643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_operationPrograms[step] = program; 12663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_operationResultStorages[step] = genResultStorage(); 12673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 12683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry break; 12693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 12703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case InterCallOperations::Command::TYPE_READ_ZERO: 12723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 12733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const op::ReadZeroData& cmd = m_cmds[step].u_cmd.readZero; 12743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // new storage handle? 12763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_storageIDs.find(cmd.targetHandle) == m_storageIDs.end()) 12773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_storageIDs[cmd.targetHandle] = genStorage(cmd.targetHandle); 12783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // program 12803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 12813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glu::ShaderProgram* program = genReadZeroProgram(); 12823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Program #" << ++programFriendlyName << tcu::TestLog::EndMessage; 12843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << *program; 12853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!program->isOk()) 12873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw tcu::TestError("could not build program"); 12883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_operationPrograms[step] = program; 12903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_operationResultStorages[step] = genResultStorage(); 12913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 12923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry break; 12933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 12943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry default: 12963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(DE_FALSE); 12973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 12983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 12993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 13003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13013c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid InterCallTestCase::deinit (void) 13023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 13033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // programs 13043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < (int)m_operationPrograms.size(); ++ndx) 13053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry delete m_operationPrograms[ndx]; 13063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_operationPrograms.clear(); 13073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // result storages 13093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < (int)m_operationResultStorages.size(); ++ndx) 13103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 13113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_operationResultStorages[ndx]) 13123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_context.getRenderContext().getFunctions().deleteBuffers(1, &m_operationResultStorages[ndx]); 13133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 13143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_operationResultStorages.clear(); 13153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // storage 13173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (std::map<int, glw::GLuint>::const_iterator it = m_storageIDs.begin(); it != m_storageIDs.end(); ++it) 13183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 13193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 13203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_storage == STORAGE_BUFFER) 13223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.deleteBuffers(1, &it->second); 13233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_storage == STORAGE_IMAGE) 13243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.deleteTextures(1, &it->second); 13253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 13263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(DE_FALSE); 13273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 13283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_storageIDs.clear(); 13293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 13303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13313c827367444ee418f129b2c238299f49d3264554Jarkko PoyryInterCallTestCase::IterateResult InterCallTestCase::iterate (void) 13323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 13333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int programFriendlyName = 0; 13343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int resultStorageFriendlyName = 0; 13353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Running operations:" << tcu::TestLog::EndMessage; 13373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // run steps 13393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int step = 0; step < (int)m_cmds.size(); ++step) 13413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 13423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry switch (m_cmds[step].type) 13433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 13443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case InterCallOperations::Command::TYPE_WRITE: runCommand(m_cmds[step].u_cmd.write, step, programFriendlyName); break; 13453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case InterCallOperations::Command::TYPE_READ: runCommand(m_cmds[step].u_cmd.read, step, programFriendlyName, resultStorageFriendlyName); break; 13463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case InterCallOperations::Command::TYPE_BARRIER: runCommand(m_cmds[step].u_cmd.barrier); break; 13473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case InterCallOperations::Command::TYPE_READ_MULTIPLE: runCommand(m_cmds[step].u_cmd.readMulti, step, programFriendlyName, resultStorageFriendlyName); break; 13483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case InterCallOperations::Command::TYPE_WRITE_INTERLEAVE: runCommand(m_cmds[step].u_cmd.writeInterleave, step, programFriendlyName); break; 13493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case InterCallOperations::Command::TYPE_READ_INTERLEAVE: runCommand(m_cmds[step].u_cmd.readInterleave, step, programFriendlyName, resultStorageFriendlyName); break; 13503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case InterCallOperations::Command::TYPE_READ_ZERO: runCommand(m_cmds[step].u_cmd.readZero, step, programFriendlyName, resultStorageFriendlyName); break; 13513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry default: 13523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(DE_FALSE); 13533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 13543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 13553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // read results from result buffers 13573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (verifyResults()) 13583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 13593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 13603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, (std::string((m_storage == STORAGE_BUFFER) ? ("buffer") : ("image")) + " content verification failed").c_str()); 13613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return STOP; 13633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 13643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13653c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool InterCallTestCase::verifyResults (void) 13663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 13673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int resultBufferFriendlyName = 0; 13683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool allResultsOk = true; 13693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool anyResult = false; 13703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Reading verifier program results" << tcu::TestLog::EndMessage; 13723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int step = 0; step < (int)m_cmds.size(); ++step) 13743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 13753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int errorFloodThreshold = 5; 13763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int numErrorsLogged = 0; 13773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_operationResultStorages[step]) 13793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 13803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 13813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const void* mapped = DE_NULL; 13823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::vector<deInt32> results (m_invocationGridSize * m_invocationGridSize); 13833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool error = false; 13843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry anyResult = true; 13863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindBuffer(GL_SHADER_STORAGE_BUFFER, m_operationResultStorages[step]); 13883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry mapped = gl.mapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, m_invocationGridSize * m_invocationGridSize * sizeof(deUint32), GL_MAP_READ_BIT); 13893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "map buffer"); 13903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // copy to properly aligned array 13923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deMemcpy(&results[0], mapped, m_invocationGridSize * m_invocationGridSize * sizeof(deUint32)); 13933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (gl.unmapBuffer(GL_SHADER_STORAGE_BUFFER) != GL_TRUE) 13953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw tcu::TestError("memory map store corrupted"); 13963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // check the results 13983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < (int)results.size(); ++ndx) 13993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 14003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (results[ndx] != 1) 14013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 14023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry error = true; 14033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 14043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (numErrorsLogged == 0) 14053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Result storage #" << ++resultBufferFriendlyName << " failed, got unexpected values.\n" << tcu::TestLog::EndMessage; 14063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (numErrorsLogged++ < errorFloodThreshold) 14073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << " Error at index " << ndx << ": expected 1, got " << results[ndx] << ".\n" << tcu::TestLog::EndMessage; 14083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 14093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 14103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // after N errors, no point continuing verification 14113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << " -- too many errors, skipping verification --\n" << tcu::TestLog::EndMessage; 14123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry break; 14133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 14143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 14153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 14163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 14173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (error) 14183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 14193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry allResultsOk = false; 14203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 14213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 14223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Result storage #" << ++resultBufferFriendlyName << " ok." << tcu::TestLog::EndMessage; 14233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 14243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 14253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 14263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(anyResult); 14273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_UNREF(anyResult); 14283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 14293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return allResultsOk; 14303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 14313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 14323c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid InterCallTestCase::runCommand (const op::WriteData& cmd, int stepNdx, int& programFriendlyName) 14333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 14343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 14353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 14363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() 14373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << tcu::TestLog::Message 14383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "Running program #" << ++programFriendlyName << " to write " << ((m_storage == STORAGE_BUFFER) ? ("buffer") : ("image")) << " #" << cmd.targetHandle << ".\n" 14393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " Dispatch size: " << m_invocationGridSize << "x" << m_invocationGridSize << "." 14403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << tcu::TestLog::EndMessage; 14413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 14423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.useProgram(m_operationPrograms[stepNdx]->getProgram()); 14433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 14443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // set destination 14453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_storage == STORAGE_BUFFER) 14463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 14473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(m_storageIDs[cmd.targetHandle]); 14483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 14493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_storageIDs[cmd.targetHandle]); 14503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "bind destination buffer"); 14513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 14523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_storage == STORAGE_IMAGE) 14533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 14543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(m_storageIDs[cmd.targetHandle]); 14553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 14563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindImageTexture(0, m_storageIDs[cmd.targetHandle], 0, GL_FALSE, 0, (m_useAtomic) ? (GL_READ_WRITE) : (GL_WRITE_ONLY), (m_formatInteger) ? (GL_R32I) : (GL_R32F)); 14573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "bind destination image"); 14583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 14593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 14603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(DE_FALSE); 14613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 14623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // calc 14633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.dispatchCompute(m_invocationGridSize, m_invocationGridSize, 1); 14643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "dispatch write"); 14653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 14663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 14673c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid InterCallTestCase::runCommand (const op::ReadData& cmd, int stepNdx, int& programFriendlyName, int& resultStorageFriendlyName) 14683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 14693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry runSingleRead(cmd.targetHandle, stepNdx, programFriendlyName, resultStorageFriendlyName); 14703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 14713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 14723c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid InterCallTestCase::runCommand (const op::Barrier& cmd) 14733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 14743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 14753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 14763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_UNREF(cmd); 14773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 14783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_storage == STORAGE_BUFFER) 14793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 14803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Memory Barrier\n\tbits = GL_SHADER_STORAGE_BARRIER_BIT" << tcu::TestLog::EndMessage; 14813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.memoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT); 14823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 14833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_storage == STORAGE_IMAGE) 14843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 14853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Memory Barrier\n\tbits = GL_SHADER_IMAGE_ACCESS_BARRIER_BIT" << tcu::TestLog::EndMessage; 14863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.memoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT); 14873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 14883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 14893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(DE_FALSE); 14903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 14913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 14923c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid InterCallTestCase::runCommand (const op::ReadMultipleData& cmd, int stepNdx, int& programFriendlyName, int& resultStorageFriendlyName) 14933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 14943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 14953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 14963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() 14973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << tcu::TestLog::Message 14983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "Running program #" << ++programFriendlyName << " to verify " << ((m_storage == STORAGE_BUFFER) ? ("buffers") : ("images")) << " #" << cmd.targetHandle0 << " and #" << cmd.targetHandle1 << ".\n" 14993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " Writing results to result storage #" << ++resultStorageFriendlyName << ".\n" 15003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " Dispatch size: " << m_invocationGridSize << "x" << m_invocationGridSize << "." 15013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << tcu::TestLog::EndMessage; 15023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.useProgram(m_operationPrograms[stepNdx]->getProgram()); 15043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // set sources 15063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_storage == STORAGE_BUFFER) 15073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 15083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(m_storageIDs[cmd.targetHandle0]); 15093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(m_storageIDs[cmd.targetHandle1]); 15103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_storageIDs[cmd.targetHandle0]); 15123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, m_storageIDs[cmd.targetHandle1]); 15133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "bind source buffers"); 15143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 15153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_storage == STORAGE_IMAGE) 15163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 15173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(m_storageIDs[cmd.targetHandle0]); 15183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(m_storageIDs[cmd.targetHandle1]); 15193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindImageTexture(1, m_storageIDs[cmd.targetHandle0], 0, GL_FALSE, 0, (m_useAtomic) ? (GL_READ_WRITE) : (GL_READ_ONLY), (m_formatInteger) ? (GL_R32I) : (GL_R32F)); 15213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindImageTexture(2, m_storageIDs[cmd.targetHandle1], 0, GL_FALSE, 0, (m_useAtomic) ? (GL_READ_WRITE) : (GL_READ_ONLY), (m_formatInteger) ? (GL_R32I) : (GL_R32F)); 15223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "bind source images"); 15233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 15243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 15253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(DE_FALSE); 15263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // set destination 15283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(m_operationResultStorages[stepNdx]); 15293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_operationResultStorages[stepNdx]); 15303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "bind result buffer"); 15313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // calc 15333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.dispatchCompute(m_invocationGridSize, m_invocationGridSize, 1); 15343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "dispatch read multi"); 15353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 15363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15373c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid InterCallTestCase::runCommand (const op::WriteDataInterleaved& cmd, int stepNdx, int& programFriendlyName) 15383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 15393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 15403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() 15423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << tcu::TestLog::Message 15433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "Running program #" << ++programFriendlyName << " to write " << ((m_storage == STORAGE_BUFFER) ? ("buffer") : ("image")) << " #" << cmd.targetHandle << ".\n" 15443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " Writing to every " << ((cmd.evenOdd) ? ("even") : ("odd")) << " " << ((m_storage == STORAGE_BUFFER) ? ("element") : ("column")) << ".\n" 15453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " Dispatch size: " << m_invocationGridSize / 2 << "x" << m_invocationGridSize << "." 15463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << tcu::TestLog::EndMessage; 15473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.useProgram(m_operationPrograms[stepNdx]->getProgram()); 15493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // set destination 15513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_storage == STORAGE_BUFFER) 15523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 15533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(m_storageIDs[cmd.targetHandle]); 15543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_storageIDs[cmd.targetHandle]); 15563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "bind destination buffer"); 15573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 15583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_storage == STORAGE_IMAGE) 15593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 15603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(m_storageIDs[cmd.targetHandle]); 15613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindImageTexture(0, m_storageIDs[cmd.targetHandle], 0, GL_FALSE, 0, (m_useAtomic) ? (GL_READ_WRITE) : (GL_WRITE_ONLY), (m_formatInteger) ? (GL_R32I) : (GL_R32F)); 15633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "bind destination image"); 15643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 15653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 15663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(DE_FALSE); 15673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // calc 15693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.dispatchCompute(m_invocationGridSize / 2, m_invocationGridSize, 1); 15703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "dispatch write"); 15713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 15723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15733c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid InterCallTestCase::runCommand (const op::ReadDataInterleaved& cmd, int stepNdx, int& programFriendlyName, int& resultStorageFriendlyName) 15743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 15753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry runSingleRead(cmd.targetHandle, stepNdx, programFriendlyName, resultStorageFriendlyName); 15763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 15773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15783c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid InterCallTestCase::runCommand (const op::ReadZeroData& cmd, int stepNdx, int& programFriendlyName, int& resultStorageFriendlyName) 15793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 15803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry runSingleRead(cmd.targetHandle, stepNdx, programFriendlyName, resultStorageFriendlyName); 15813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 15823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15833c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid InterCallTestCase::runSingleRead (int targetHandle, int stepNdx, int& programFriendlyName, int& resultStorageFriendlyName) 15843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 15853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 15863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() 15883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << tcu::TestLog::Message 15893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "Running program #" << ++programFriendlyName << " to verify " << ((m_storage == STORAGE_BUFFER) ? ("buffer") : ("image")) << " #" << targetHandle << ".\n" 15903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " Writing results to result storage #" << ++resultStorageFriendlyName << ".\n" 15913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " Dispatch size: " << m_invocationGridSize << "x" << m_invocationGridSize << "." 15923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << tcu::TestLog::EndMessage; 15933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.useProgram(m_operationPrograms[stepNdx]->getProgram()); 15953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // set source 15973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_storage == STORAGE_BUFFER) 15983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 15993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(m_storageIDs[targetHandle]); 16003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_storageIDs[targetHandle]); 16023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "bind source buffer"); 16033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 16043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_storage == STORAGE_IMAGE) 16053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 16063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(m_storageIDs[targetHandle]); 16073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindImageTexture(1, m_storageIDs[targetHandle], 0, GL_FALSE, 0, (m_useAtomic) ? (GL_READ_WRITE) : (GL_READ_ONLY), (m_formatInteger) ? (GL_R32I) : (GL_R32F)); 16093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "bind source image"); 16103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 16113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 16123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(DE_FALSE); 16133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // set destination 16153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(m_operationResultStorages[stepNdx]); 16163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_operationResultStorages[stepNdx]); 16173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "bind result buffer"); 16183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // calc 16203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.dispatchCompute(m_invocationGridSize, m_invocationGridSize, 1); 16213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "dispatch read"); 16223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 16233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16243c827367444ee418f129b2c238299f49d3264554Jarkko Poyryglw::GLuint InterCallTestCase::genStorage (int friendlyName) 16253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 16263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 16273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_storage == STORAGE_BUFFER) 16293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 16303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numElements = m_invocationGridSize * m_invocationGridSize * m_perInvocationSize; 16313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int bufferSize = numElements * ((m_formatInteger) ? (sizeof(deInt32)) : (sizeof(glw::GLfloat))); 16323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glw::GLuint retVal = 0; 16333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Creating buffer #" << friendlyName << ", size " << bufferSize << " bytes." << tcu::TestLog::EndMessage; 16353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.genBuffers(1, &retVal); 16373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindBuffer(GL_SHADER_STORAGE_BUFFER, retVal); 16383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_formatInteger) 16403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 16413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const std::vector<deUint32> zeroBuffer(numElements, 0); 16423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bufferData(GL_SHADER_STORAGE_BUFFER, bufferSize, &zeroBuffer[0], GL_STATIC_DRAW); 16433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 16443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 16453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 16463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const std::vector<float> zeroBuffer(numElements, 0.0f); 16473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bufferData(GL_SHADER_STORAGE_BUFFER, bufferSize, &zeroBuffer[0], GL_STATIC_DRAW); 16483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 16493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "gen buffer"); 16503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return retVal; 16523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 16533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_storage == STORAGE_IMAGE) 16543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 16553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int imageWidth = m_invocationGridSize; 16563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int imageHeight = m_invocationGridSize * m_perInvocationSize; 16573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glw::GLuint retVal = 0; 16583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() 16603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << tcu::TestLog::Message 16613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "Creating image #" << friendlyName << ", size " << imageWidth << "x" << imageHeight 16623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << ", internalformat = " << ((m_formatInteger) ? ("r32i") : ("r32f")) 16633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << ", size = " << (imageWidth*imageHeight*sizeof(deUint32)) << " bytes." 16643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << tcu::TestLog::EndMessage; 16653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.genTextures(1, &retVal); 16673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindTexture(GL_TEXTURE_2D, retVal); 16683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_formatInteger) 16708852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry gl.texStorage2D(GL_TEXTURE_2D, 1, GL_R32I, imageWidth, imageHeight); 16718852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry else 16728852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry gl.texStorage2D(GL_TEXTURE_2D, 1, GL_R32F, imageWidth, imageHeight); 16738852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 16748852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 16758852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 16768852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "gen image"); 16778852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 16788852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry m_testCtx.getLog() 16798852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry << tcu::TestLog::Message 16808852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry << "Filling image with 0" 16818852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry << tcu::TestLog::EndMessage; 16828852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 16838852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry if (m_formatInteger) 16843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 16858852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const std::vector<deInt32> zeroBuffer(imageWidth * imageHeight, 0); 16868852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry gl.texSubImage2D(GL_TEXTURE_2D, 0, 0, 0, imageWidth, imageHeight, GL_RED_INTEGER, GL_INT, &zeroBuffer[0]); 16873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 16883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 16893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 16903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const std::vector<float> zeroBuffer(imageWidth * imageHeight, 0.0f); 16918852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry gl.texSubImage2D(GL_TEXTURE_2D, 0, 0, 0, imageWidth, imageHeight, GL_RED, GL_FLOAT, &zeroBuffer[0]); 16923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 16933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16948852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "specify image contents"); 16953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return retVal; 16973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 16983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 16993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 17003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(DE_FALSE); 17013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return 0; 17023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 17033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 17043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17053c827367444ee418f129b2c238299f49d3264554Jarkko Poyryglw::GLuint InterCallTestCase::genResultStorage (void) 17063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 17073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 17083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glw::GLuint retVal = 0; 17093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.genBuffers(1, &retVal); 17113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindBuffer(GL_SHADER_STORAGE_BUFFER, retVal); 17123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bufferData(GL_SHADER_STORAGE_BUFFER, m_invocationGridSize * m_invocationGridSize * sizeof(deUint32), DE_NULL, GL_STATIC_DRAW); 17133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "gen buffer"); 17143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return retVal; 17163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 17173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17183c827367444ee418f129b2c238299f49d3264554Jarkko Poyryglu::ShaderProgram* InterCallTestCase::genWriteProgram (int seed) 17193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 17203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool useImageAtomics = m_useAtomic && m_storage == STORAGE_IMAGE; 17213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::ostringstream buf; 17223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "#version 310 es\n" 17243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << ((useImageAtomics) ? ("#extension GL_OES_shader_image_atomic : require\n") : ("")) 17253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "layout (local_size_x = 1, local_size_y = 1) in;\n"; 17263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_storage == STORAGE_BUFFER) 17283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "layout(binding=0, std430) " << ((m_useAtomic) ? ("coherent ") : ("")) << "buffer Buffer\n" 17293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "{\n" 17303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " highp " << ((m_formatInteger) ? ("int") : ("float")) << " values[];\n" 17313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "} sb_out;\n"; 17323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_storage == STORAGE_IMAGE) 17333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "layout(" << ((m_formatInteger) ? ("r32i") : ("r32f")) << ", binding=0) " << ((m_useAtomic) ? ("coherent ") : ("writeonly ")) << "uniform highp " << ((m_formatInteger) ? ("iimage2D") : ("image2D")) << " u_imageOut;\n"; 17343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 17353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(DE_FALSE); 17363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "\n" 17383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "void main (void)\n" 17393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "{\n" 17403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " uvec3 size = gl_NumWorkGroups * gl_WorkGroupSize;\n" 17413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " int groupNdx = int(size.x * size.y * gl_GlobalInvocationID.z + size.x*gl_GlobalInvocationID.y + gl_GlobalInvocationID.x);\n" 17423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "\n"; 17433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Write to buffer/image m_perInvocationSize elements 17453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_storage == STORAGE_BUFFER) 17463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 17473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int writeNdx = 0; writeNdx < m_perInvocationSize; ++writeNdx) 17483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 17493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_useAtomic) 17503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << " atomicExchange("; 17513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 17523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << " "; 17533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "sb_out.values[(groupNdx + " << seed + writeNdx*m_invocationGridSize*m_invocationGridSize << ") % " << m_invocationGridSize*m_invocationGridSize*m_perInvocationSize << "]"; 17553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_useAtomic) 17573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << ", " << ((m_formatInteger) ? ("int") : ("float")) << "(groupNdx));\n"; 17583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 17593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << " = " << ((m_formatInteger) ? ("int") : ("float")) << "(groupNdx);\n"; 17603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 17613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 17623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_storage == STORAGE_IMAGE) 17633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 17643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int writeNdx = 0; writeNdx < m_perInvocationSize; ++writeNdx) 17653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 17663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_useAtomic) 17673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << " imageAtomicExchange"; 17683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 17693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << " imageStore"; 17703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "(u_imageOut, ivec2((int(gl_GlobalInvocationID.x) + " << (seed + writeNdx*100) << ") % " << m_invocationGridSize << ", int(gl_GlobalInvocationID.y) + " << writeNdx*m_invocationGridSize << "), "; 17723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_useAtomic) 17743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << ((m_formatInteger) ? ("int") : ("float")) << "(groupNdx));\n"; 17753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 17763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << ((m_formatInteger) ? ("ivec4(int(groupNdx), 0, 0, 0)") : ("vec4(float(groupNdx), 0.0, 0.0, 0.0)")) << ");\n"; 17773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 17783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 17793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 17803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(DE_FALSE); 17813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "}\n"; 17833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources() << glu::ComputeSource(buf.str())); 17853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 17863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17873c827367444ee418f129b2c238299f49d3264554Jarkko Poyryglu::ShaderProgram* InterCallTestCase::genReadProgram (int seed) 17883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 17893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool useImageAtomics = m_useAtomic && m_storage == STORAGE_IMAGE; 17903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::ostringstream buf; 17913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "#version 310 es\n" 17933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << ((useImageAtomics) ? ("#extension GL_OES_shader_image_atomic : require\n") : ("")) 17943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "layout (local_size_x = 1, local_size_y = 1) in;\n"; 17953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_storage == STORAGE_BUFFER) 17973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "layout(binding=1, std430) " << ((m_useAtomic) ? ("coherent ") : ("")) << "buffer Buffer\n" 17983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "{\n" 17993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " highp " << ((m_formatInteger) ? ("int") : ("float")) << " values[];\n" 18003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "} sb_in;\n"; 18013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_storage == STORAGE_IMAGE) 18023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "layout(" << ((m_formatInteger) ? ("r32i") : ("r32f")) << ", binding=1) " << ((m_useAtomic) ? ("coherent ") : ("readonly ")) << "uniform highp " << ((m_formatInteger) ? ("iimage2D") : ("image2D")) << " u_imageIn;\n"; 18033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 18043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(DE_FALSE); 18053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 18063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "layout(binding=0, std430) buffer ResultBuffer\n" 18073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "{\n" 18083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " highp int resultOk[];\n" 18093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "} sb_result;\n" 18103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "\n" 18113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "void main (void)\n" 18123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "{\n" 18133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " uvec3 size = gl_NumWorkGroups * gl_WorkGroupSize;\n" 18143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " int groupNdx = int(size.x * size.y * gl_GlobalInvocationID.z + size.x*gl_GlobalInvocationID.y + gl_GlobalInvocationID.x);\n" 18153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " " << ((m_formatInteger) ? ("int") : ("float")) << " zero = " << ((m_formatInteger) ? ("0") : ("0.0")) << ";\n" 18163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " bool allOk = true;\n" 18173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "\n"; 18183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 18193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Verify data 18203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 18213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_storage == STORAGE_BUFFER) 18223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 18233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int readNdx = 0; readNdx < m_perInvocationSize; ++readNdx) 18248852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry { 18258852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry if (!m_useAtomic) 18268852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry buf << " allOk = allOk && (sb_in.values[(groupNdx + " 18278852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry << seed + readNdx*m_invocationGridSize*m_invocationGridSize << ") % " << m_invocationGridSize*m_invocationGridSize*m_perInvocationSize << "] == " 18288852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry << ((m_formatInteger) ? ("int") : ("float")) << "(groupNdx));\n"; 18298852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry else 18308852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry buf << " allOk = allOk && (atomicExchange(sb_in.values[(groupNdx + " 18318852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry << seed + readNdx*m_invocationGridSize*m_invocationGridSize << ") % " << m_invocationGridSize*m_invocationGridSize*m_perInvocationSize << "], zero) == " 18328852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry << ((m_formatInteger) ? ("int") : ("float")) << "(groupNdx));\n"; 18338852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry } 18343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 18353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_storage == STORAGE_IMAGE) 18363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 18373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int readNdx = 0; readNdx < m_perInvocationSize; ++readNdx) 18388852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry { 18398852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry if (!m_useAtomic) 18408852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry buf << " allOk = allOk && (imageLoad(u_imageIn, ivec2((gl_GlobalInvocationID.x + " 18418852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry << (seed + readNdx*100) << "u) % " << m_invocationGridSize << "u, gl_GlobalInvocationID.y + " << readNdx*m_invocationGridSize << "u)).x == " 18428852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry << ((m_formatInteger) ? ("int") : ("float")) << "(groupNdx));\n"; 18438852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry else 18448852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry buf << " allOk = allOk && (imageAtomicExchange(u_imageIn, ivec2((gl_GlobalInvocationID.x + " 18458852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry << (seed + readNdx*100) << "u) % " << m_invocationGridSize << "u, gl_GlobalInvocationID.y + " << readNdx*m_invocationGridSize << "u), zero) == " 18468852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry << ((m_formatInteger) ? ("int") : ("float")) << "(groupNdx));\n"; 18478852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry } 18483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 18493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 18503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(DE_FALSE); 18513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 18523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << " sb_result.resultOk[groupNdx] = (allOk) ? (1) : (0);\n" 18533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "}\n"; 18543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 18553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources() << glu::ComputeSource(buf.str())); 18563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 18573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 18583c827367444ee418f129b2c238299f49d3264554Jarkko Poyryglu::ShaderProgram* InterCallTestCase::genReadMultipleProgram (int seed0, int seed1) 18593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 18603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool useImageAtomics = m_useAtomic && m_storage == STORAGE_IMAGE; 18613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::ostringstream buf; 18623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 18633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "#version 310 es\n" 18643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << ((useImageAtomics) ? ("#extension GL_OES_shader_image_atomic : require\n") : ("")) 18653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "layout (local_size_x = 1, local_size_y = 1) in;\n"; 18663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 18673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_storage == STORAGE_BUFFER) 18683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "layout(binding=1, std430) " << ((m_useAtomic) ? ("coherent ") : ("")) << "buffer Buffer0\n" 18693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "{\n" 18703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " highp " << ((m_formatInteger) ? ("int") : ("float")) << " values[];\n" 18713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "} sb_in0;\n" 18723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "layout(binding=2, std430) " << ((m_useAtomic) ? ("coherent ") : ("")) << "buffer Buffer1\n" 18733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "{\n" 18743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " highp " << ((m_formatInteger) ? ("int") : ("float")) << " values[];\n" 18753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "} sb_in1;\n"; 18763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_storage == STORAGE_IMAGE) 18773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "layout(" << ((m_formatInteger) ? ("r32i") : ("r32f")) << ", binding=1) " << ((m_useAtomic) ? ("coherent ") : ("readonly ")) << "uniform highp " << ((m_formatInteger) ? ("iimage2D") : ("image2D")) << " u_imageIn0;\n" 18783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "layout(" << ((m_formatInteger) ? ("r32i") : ("r32f")) << ", binding=2) " << ((m_useAtomic) ? ("coherent ") : ("readonly ")) << "uniform highp " << ((m_formatInteger) ? ("iimage2D") : ("image2D")) << " u_imageIn1;\n"; 18793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 18803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(DE_FALSE); 18813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 18823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "layout(binding=0, std430) buffer ResultBuffer\n" 18833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "{\n" 18843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " highp int resultOk[];\n" 18853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "} sb_result;\n" 18863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "\n" 18873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "void main (void)\n" 18883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "{\n" 18893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " uvec3 size = gl_NumWorkGroups * gl_WorkGroupSize;\n" 18903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " int groupNdx = int(size.x * size.y * gl_GlobalInvocationID.z + size.x*gl_GlobalInvocationID.y + gl_GlobalInvocationID.x);\n" 18913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " " << ((m_formatInteger) ? ("int") : ("float")) << " zero = " << ((m_formatInteger) ? ("0") : ("0.0")) << ";\n" 18923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " bool allOk = true;\n" 18933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "\n"; 18943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 18953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Verify data 18963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 18973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_storage == STORAGE_BUFFER) 18983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 18993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int readNdx = 0; readNdx < m_perInvocationSize; ++readNdx) 19003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << " allOk = allOk && (" << ((m_useAtomic) ? ("atomicExchange(") : ("")) << "sb_in0.values[(groupNdx + " << seed0 + readNdx*m_invocationGridSize*m_invocationGridSize << ") % " << m_invocationGridSize*m_invocationGridSize*m_perInvocationSize << "]" << ((m_useAtomic) ? (", zero)") : ("")) << " == " << ((m_formatInteger) ? ("int") : ("float")) << "(groupNdx));\n" 19013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " allOk = allOk && (" << ((m_useAtomic) ? ("atomicExchange(") : ("")) << "sb_in1.values[(groupNdx + " << seed1 + readNdx*m_invocationGridSize*m_invocationGridSize << ") % " << m_invocationGridSize*m_invocationGridSize*m_perInvocationSize << "]" << ((m_useAtomic) ? (", zero)") : ("")) << " == " << ((m_formatInteger) ? ("int") : ("float")) << "(groupNdx));\n"; 19023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 19033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_storage == STORAGE_IMAGE) 19043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 19053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int readNdx = 0; readNdx < m_perInvocationSize; ++readNdx) 19068852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry buf << " allOk = allOk && (" << ((m_useAtomic) ? ("imageAtomicExchange") : ("imageLoad")) << "(u_imageIn0, ivec2((gl_GlobalInvocationID.x + " << (seed0 + readNdx*100) << "u) % " << m_invocationGridSize << "u, gl_GlobalInvocationID.y + " << readNdx*m_invocationGridSize << "u)" << ((m_useAtomic) ? (", zero)") : (").x")) << " == " << ((m_formatInteger) ? ("int") : ("float")) << "(groupNdx));\n" 19078852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry << " allOk = allOk && (" << ((m_useAtomic) ? ("imageAtomicExchange") : ("imageLoad")) << "(u_imageIn1, ivec2((gl_GlobalInvocationID.x + " << (seed1 + readNdx*100) << "u) % " << m_invocationGridSize << "u, gl_GlobalInvocationID.y + " << readNdx*m_invocationGridSize << "u)" << ((m_useAtomic) ? (", zero)") : (").x")) << " == " << ((m_formatInteger) ? ("int") : ("float")) << "(groupNdx));\n"; 19083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 19093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 19103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(DE_FALSE); 19113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 19123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << " sb_result.resultOk[groupNdx] = (allOk) ? (1) : (0);\n" 19133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "}\n"; 19143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 19153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources() << glu::ComputeSource(buf.str())); 19163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 19173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 19183c827367444ee418f129b2c238299f49d3264554Jarkko Poyryglu::ShaderProgram* InterCallTestCase::genWriteInterleavedProgram (int seed, bool evenOdd) 19193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 19203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool useImageAtomics = m_useAtomic && m_storage == STORAGE_IMAGE; 19213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::ostringstream buf; 19223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 19233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "#version 310 es\n" 19243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << ((useImageAtomics) ? ("#extension GL_OES_shader_image_atomic : require\n") : ("")) 19253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "layout (local_size_x = 1, local_size_y = 1) in;\n"; 19263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 19273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_storage == STORAGE_BUFFER) 19283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "layout(binding=0, std430) " << ((m_useAtomic) ? ("coherent ") : ("")) << "buffer Buffer\n" 19293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "{\n" 19303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " highp " << ((m_formatInteger) ? ("int") : ("float")) << " values[];\n" 19313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "} sb_out;\n"; 19323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_storage == STORAGE_IMAGE) 19333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "layout(" << ((m_formatInteger) ? ("r32i") : ("r32f")) << ", binding=0) " << ((m_useAtomic) ? ("coherent ") : ("writeonly ")) << "uniform highp " << ((m_formatInteger) ? ("iimage2D") : ("image2D")) << " u_imageOut;\n"; 19343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 19353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(DE_FALSE); 19363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 19373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "\n" 19383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "void main (void)\n" 19393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "{\n" 19403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " uvec3 size = gl_NumWorkGroups * gl_WorkGroupSize;\n" 19413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " int groupNdx = int(size.x * size.y * gl_GlobalInvocationID.z + size.x*gl_GlobalInvocationID.y + gl_GlobalInvocationID.x);\n" 19423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "\n"; 19433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 19443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Write to buffer/image m_perInvocationSize elements 19453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_storage == STORAGE_BUFFER) 19463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 19473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int writeNdx = 0; writeNdx < m_perInvocationSize; ++writeNdx) 19483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 19493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_useAtomic) 19503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << " atomicExchange("; 19513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 19523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << " "; 19533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 19543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "sb_out.values[((groupNdx + " << seed + writeNdx*m_invocationGridSize*m_invocationGridSize / 2 << ") % " << m_invocationGridSize*m_invocationGridSize / 2 * m_perInvocationSize << ") * 2 + " << ((evenOdd) ? (0) : (1)) << "]"; 19553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 19563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_useAtomic) 19573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << ", " << ((m_formatInteger) ? ("int") : ("float")) << "(groupNdx));\n"; 19583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 19593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "= " << ((m_formatInteger) ? ("int") : ("float")) << "(groupNdx);\n"; 19603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 19613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 19623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_storage == STORAGE_IMAGE) 19633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 19643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int writeNdx = 0; writeNdx < m_perInvocationSize; ++writeNdx) 19653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 19663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_useAtomic) 19673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << " imageAtomicExchange"; 19683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 19693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << " imageStore"; 19703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 19713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "(u_imageOut, ivec2(((int(gl_GlobalInvocationID.x) + " << (seed + writeNdx*100) << ") % " << m_invocationGridSize / 2 << ") * 2 + " << ((evenOdd) ? (0) : (1)) << ", int(gl_GlobalInvocationID.y) + " << writeNdx*m_invocationGridSize << "), "; 19723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 19733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_useAtomic) 19743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << ((m_formatInteger) ? ("int") : ("float")) << "(groupNdx));\n"; 19753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 19763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << ((m_formatInteger) ? ("ivec4(int(groupNdx), 0, 0, 0)") : ("vec4(float(groupNdx), 0.0, 0.0, 0.0)")) << ");\n"; 19773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 19783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 19793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 19803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(DE_FALSE); 19813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 19823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "}\n"; 19833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 19843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources() << glu::ComputeSource(buf.str())); 19853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 19863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 19873c827367444ee418f129b2c238299f49d3264554Jarkko Poyryglu::ShaderProgram* InterCallTestCase::genReadInterleavedProgram (int seed0, int seed1) 19883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 19893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool useImageAtomics = m_useAtomic && m_storage == STORAGE_IMAGE; 19903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::ostringstream buf; 19913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 19923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "#version 310 es\n" 19933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << ((useImageAtomics) ? ("#extension GL_OES_shader_image_atomic : require\n") : ("")) 19943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "layout (local_size_x = 1, local_size_y = 1) in;\n"; 19953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 19963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_storage == STORAGE_BUFFER) 19973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "layout(binding=1, std430) " << ((m_useAtomic) ? ("coherent ") : ("")) << "buffer Buffer\n" 19983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "{\n" 19993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " highp " << ((m_formatInteger) ? ("int") : ("float")) << " values[];\n" 20003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "} sb_in;\n"; 20013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_storage == STORAGE_IMAGE) 20023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "layout(" << ((m_formatInteger) ? ("r32i") : ("r32f")) << ", binding=1) " << ((m_useAtomic) ? ("coherent ") : ("readonly ")) << "uniform highp " << ((m_formatInteger) ? ("iimage2D") : ("image2D")) << " u_imageIn;\n"; 20033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 20043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(DE_FALSE); 20053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 20063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "layout(binding=0, std430) buffer ResultBuffer\n" 20073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "{\n" 20083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " highp int resultOk[];\n" 20093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "} sb_result;\n" 20103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "\n" 20113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "void main (void)\n" 20123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "{\n" 20133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " uvec3 size = gl_NumWorkGroups * gl_WorkGroupSize;\n" 20143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " int groupNdx = int(size.x * size.y * gl_GlobalInvocationID.z + size.x*gl_GlobalInvocationID.y + gl_GlobalInvocationID.x);\n" 20153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " int interleavedGroupNdx = int((size.x >> 1U) * size.y * gl_GlobalInvocationID.z + (size.x >> 1U) * gl_GlobalInvocationID.y + (gl_GlobalInvocationID.x >> 1U));\n" 20163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " " << ((m_formatInteger) ? ("int") : ("float")) << " zero = " << ((m_formatInteger) ? ("0") : ("0.0")) << ";\n" 20173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " bool allOk = true;\n" 20183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "\n"; 20193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 20203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Verify data 20213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 20223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_storage == STORAGE_BUFFER) 20233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 20243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << " if (groupNdx % 2 == 0)\n" 20253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " {\n"; 20263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int readNdx = 0; readNdx < m_perInvocationSize; ++readNdx) 20273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << " allOk = allOk && (" 20283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << ((m_useAtomic) ? ("atomicExchange(") : ("")) << "sb_in.values[((interleavedGroupNdx + " << seed0 + readNdx*m_invocationGridSize*m_invocationGridSize / 2 << ") % " << m_invocationGridSize*m_invocationGridSize*m_perInvocationSize / 2 << ") * 2 + 0]" 20293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << ((m_useAtomic) ? (", zero)") : ("")) << " == " << ((m_formatInteger) ? ("int") : ("float")) << "(interleavedGroupNdx));\n"; 20303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << " }\n" 20313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " else\n" 20323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " {\n"; 20333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int readNdx = 0; readNdx < m_perInvocationSize; ++readNdx) 20343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << " allOk = allOk && (" 20353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << ((m_useAtomic) ? ("atomicExchange(") : ("")) << "sb_in.values[((interleavedGroupNdx + " << seed1 + readNdx*m_invocationGridSize*m_invocationGridSize / 2 << ") % " << m_invocationGridSize*m_invocationGridSize*m_perInvocationSize / 2 << ") * 2 + 1]" 20363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << ((m_useAtomic) ? (", zero)") : ("")) << " == " << ((m_formatInteger) ? ("int") : ("float")) << "(interleavedGroupNdx));\n"; 20373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << " }\n"; 20383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 20393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_storage == STORAGE_IMAGE) 20403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 20413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << " if (groupNdx % 2 == 0)\n" 20423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " {\n"; 20433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int readNdx = 0; readNdx < m_perInvocationSize; ++readNdx) 20443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << " allOk = allOk && (" 20453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << ((m_useAtomic) ? ("imageAtomicExchange") : ("imageLoad")) 20463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "(u_imageIn, ivec2(((int(gl_GlobalInvocationID.x >> 1U) + " << (seed0 + readNdx*100) << ") % " << m_invocationGridSize / 2 << ") * 2 + 0, int(gl_GlobalInvocationID.y) + " << readNdx*m_invocationGridSize << ")" 20478852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry << ((m_useAtomic) ? (", zero)") : (").x")) << " == " << ((m_formatInteger) ? ("int") : ("float")) << "(interleavedGroupNdx));\n"; 20483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << " }\n" 20493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " else\n" 20503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " {\n"; 20513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int readNdx = 0; readNdx < m_perInvocationSize; ++readNdx) 20523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << " allOk = allOk && (" 20533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << ((m_useAtomic) ? ("imageAtomicExchange") : ("imageLoad")) 20543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "(u_imageIn, ivec2(((int(gl_GlobalInvocationID.x >> 1U) + " << (seed1 + readNdx*100) << ") % " << m_invocationGridSize / 2 << ") * 2 + 1, int(gl_GlobalInvocationID.y) + " << readNdx*m_invocationGridSize << ")" 20558852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry << ((m_useAtomic) ? (", zero)") : (").x")) << " == " << ((m_formatInteger) ? ("int") : ("float")) << "(interleavedGroupNdx));\n"; 20563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << " }\n"; 20573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 20583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 20593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(DE_FALSE); 20603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 20613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << " sb_result.resultOk[groupNdx] = (allOk) ? (1) : (0);\n" 20623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "}\n"; 20633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 20643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources() << glu::ComputeSource(buf.str())); 20653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 20663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 20673c827367444ee418f129b2c238299f49d3264554Jarkko Poyryglu::ShaderProgram* InterCallTestCase::genReadZeroProgram (void) 20683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 20693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool useImageAtomics = m_useAtomic && m_storage == STORAGE_IMAGE; 20703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::ostringstream buf; 20713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 20723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "#version 310 es\n" 20733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << ((useImageAtomics) ? ("#extension GL_OES_shader_image_atomic : require\n") : ("")) 20743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "layout (local_size_x = 1, local_size_y = 1) in;\n"; 20753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 20763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_storage == STORAGE_BUFFER) 20773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "layout(binding=1, std430) " << ((m_useAtomic) ? ("coherent ") : ("")) << "buffer Buffer\n" 20783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "{\n" 20793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " highp " << ((m_formatInteger) ? ("int") : ("float")) << " values[];\n" 20803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "} sb_in;\n"; 20813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_storage == STORAGE_IMAGE) 20823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "layout(" << ((m_formatInteger) ? ("r32i") : ("r32f")) << ", binding=1) " << ((m_useAtomic) ? ("coherent ") : ("readonly ")) << "uniform highp " << ((m_formatInteger) ? ("iimage2D") : ("image2D")) << " u_imageIn;\n"; 20833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 20843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(DE_FALSE); 20853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 20863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "layout(binding=0, std430) buffer ResultBuffer\n" 20873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "{\n" 20883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " highp int resultOk[];\n" 20893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "} sb_result;\n" 20903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "\n" 20913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "void main (void)\n" 20923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "{\n" 20933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " uvec3 size = gl_NumWorkGroups * gl_WorkGroupSize;\n" 20943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " int groupNdx = int(size.x * size.y * gl_GlobalInvocationID.z + size.x*gl_GlobalInvocationID.y + gl_GlobalInvocationID.x);\n" 20953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " " << ((m_formatInteger) ? ("int") : ("float")) << " anything = " << ((m_formatInteger) ? ("5") : ("5.0")) << ";\n" 20963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " bool allOk = true;\n" 20973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "\n"; 20983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 20993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Verify data 21003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 21013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_storage == STORAGE_BUFFER) 21023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 21033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int readNdx = 0; readNdx < m_perInvocationSize; ++readNdx) 21043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << " allOk = allOk && (" 21053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << ((m_useAtomic) ? ("atomicExchange(") : ("")) << "sb_in.values[groupNdx * " << m_perInvocationSize << " + " << readNdx << "]" 21063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << ((m_useAtomic) ? (", anything)") : ("")) << " == " << ((m_formatInteger) ? ("0") : ("0.0")) << ");\n"; 21073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 21083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_storage == STORAGE_IMAGE) 21093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 21103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int readNdx = 0; readNdx < m_perInvocationSize; ++readNdx) 21113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << " allOk = allOk && (" 21123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << ((m_useAtomic) ? ("imageAtomicExchange") : ("imageLoad")) << "(u_imageIn, ivec2(gl_GlobalInvocationID.x, gl_GlobalInvocationID.y + " << (readNdx*m_invocationGridSize) << "u)" 21138852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry << ((m_useAtomic) ? (", anything)") : (").x")) << " == " << ((m_formatInteger) ? ("0") : ("0.0")) << ");\n"; 21143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 21153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 21163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(DE_FALSE); 21173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 21183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << " sb_result.resultOk[groupNdx] = (allOk) ? (1) : (0);\n" 21193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "}\n"; 21203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 21213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources() << glu::ComputeSource(buf.str())); 21223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 21233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 21243c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass SSBOConcurrentAtomicCase : public TestCase 21253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 21263c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 21273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 21283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry SSBOConcurrentAtomicCase (Context& context, const char* name, const char* description, int numCalls, int workSize); 21293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ~SSBOConcurrentAtomicCase (void); 21303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 21313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void init (void); 21323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void deinit (void); 21333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IterateResult iterate (void); 21343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 21353c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate: 21363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::string genComputeSource (void) const; 21373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 21383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int m_numCalls; 21393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int m_workSize; 21403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glu::ShaderProgram* m_program; 21413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deUint32 m_bufferID; 21423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::vector<deUint32> m_intermediateResultBuffers; 21433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 21443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 21453c827367444ee418f129b2c238299f49d3264554Jarkko PoyrySSBOConcurrentAtomicCase::SSBOConcurrentAtomicCase (Context& context, const char* name, const char* description, int numCalls, int workSize) 21463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : TestCase (context, name, description) 21473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_numCalls (numCalls) 21483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_workSize (workSize) 21493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_program (DE_NULL) 21503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_bufferID (DE_NULL) 21513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 21523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 21533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 21543c827367444ee418f129b2c238299f49d3264554Jarkko PoyrySSBOConcurrentAtomicCase::~SSBOConcurrentAtomicCase (void) 21553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 21563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deinit(); 21573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 21583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 21593c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid SSBOConcurrentAtomicCase::init (void) 21603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 21613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 21623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::vector<deUint32> zeroData (m_workSize, 0); 21633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 21643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // gen buffers 21653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 21663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.genBuffers(1, &m_bufferID); 21673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindBuffer(GL_SHADER_STORAGE_BUFFER, m_bufferID); 21683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bufferData(GL_SHADER_STORAGE_BUFFER, sizeof(deUint32) * m_workSize, &zeroData[0], GL_DYNAMIC_COPY); 21693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 21703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < m_numCalls; ++ndx) 21713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 21723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deUint32 buffer = 0; 21733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 21743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.genBuffers(1, &buffer); 21753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindBuffer(GL_SHADER_STORAGE_BUFFER, buffer); 21763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bufferData(GL_SHADER_STORAGE_BUFFER, sizeof(deUint32) * m_workSize, &zeroData[0], GL_DYNAMIC_COPY); 21773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 21783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_intermediateResultBuffers.push_back(buffer); 21793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "gen buffers"); 21803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 21813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 21823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // gen program 21833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 21843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_program = new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources() << glu::ComputeSource(genComputeSource())); 21853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << *m_program; 21863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!m_program->isOk()) 21873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw tcu::TestError("could not build program"); 21883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 21893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 21903c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid SSBOConcurrentAtomicCase::deinit (void) 21913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 21923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_bufferID) 21933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 21943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_context.getRenderContext().getFunctions().deleteBuffers(1, &m_bufferID); 21953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_bufferID = 0; 21963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 21973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 21983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < (int)m_intermediateResultBuffers.size(); ++ndx) 21993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_context.getRenderContext().getFunctions().deleteBuffers(1, &m_intermediateResultBuffers[ndx]); 22003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_intermediateResultBuffers.clear(); 22013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 22023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry delete m_program; 22033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_program = DE_NULL; 22043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 22053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 22063c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTestCase::IterateResult SSBOConcurrentAtomicCase::iterate (void) 22073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 22083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 22093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const deUint32 sumValue = (deUint32)(m_numCalls * (m_numCalls + 1) / 2); 22103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::vector<int> deltas; 22113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 22123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // generate unique deltas 22133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry generateShuffledRamp(m_numCalls, deltas); 22143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 22153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // invoke program N times, each with a different delta 22163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 22173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int deltaLocation = gl.getUniformLocation(m_program->getProgram(), "u_atomicDelta"); 22183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 22193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() 22203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << tcu::TestLog::Message 22213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "Running shader " << m_numCalls << " times.\n" 22223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "Num groups = (" << m_workSize << ", 1, 1)\n" 22233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "Setting u_atomicDelta to a unique value for each call.\n" 22243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << tcu::TestLog::EndMessage; 22253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 22263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (deltaLocation == -1) 22273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw tcu::TestError("u_atomicDelta location was -1"); 22283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 22293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.useProgram(m_program->getProgram()); 22303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, m_bufferID); 22313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 22323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int callNdx = 0; callNdx < m_numCalls; ++callNdx) 22333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 22343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() 22353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << tcu::TestLog::Message 22363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "Call " << callNdx << ": u_atomicDelta = " << deltas[callNdx] 22373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << tcu::TestLog::EndMessage; 22383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 22393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.uniform1ui(deltaLocation, deltas[callNdx]); 22403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_intermediateResultBuffers[callNdx]); 22413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.dispatchCompute(m_workSize, 1, 1); 22423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 22433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 22443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "post dispatch"); 22453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 22463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 22473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Verify result 22483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 22493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::vector<deUint32> result; 22503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 22513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Verifying work buffer, it should be filled with value " << sumValue << tcu::TestLog::EndMessage; 22523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 22533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindBuffer(GL_SHADER_STORAGE_BUFFER, m_bufferID); 22543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry readBuffer(gl, GL_SHADER_STORAGE_BUFFER, m_workSize, result); 22553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 22563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < m_workSize; ++ndx) 22573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 22583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (result[ndx] != sumValue) 22593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 22603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() 22613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << tcu::TestLog::Message 22623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "Work buffer error, at index " << ndx << " expected value " << (sumValue) << ", got " << result[ndx] << "\n" 22633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "Work buffer contains invalid values." 22643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << tcu::TestLog::EndMessage; 22653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 22663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Buffer contents invalid"); 22673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return STOP; 22683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 22693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 22703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 22713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Work buffer contents are valid." << tcu::TestLog::EndMessage; 22723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 22733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 22743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // verify steps 22753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 22763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::vector<std::vector<deUint32> > intermediateResults (m_numCalls); 22773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::vector<deUint32> valueChain (m_numCalls); 22783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 22793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Verifying intermediate results. " << tcu::TestLog::EndMessage; 22803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 22813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // collect results 22823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 22833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int callNdx = 0; callNdx < m_numCalls; ++callNdx) 22843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 22853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindBuffer(GL_SHADER_STORAGE_BUFFER, m_intermediateResultBuffers[callNdx]); 22863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry readBuffer(gl, GL_SHADER_STORAGE_BUFFER, m_workSize, intermediateResults[callNdx]); 22873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 22883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 22893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // verify values 22903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 22913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int valueNdx = 0; valueNdx < m_workSize; ++valueNdx) 22923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 22933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int invalidOperationNdx; 22943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deUint32 errorDelta; 22953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deUint32 errorExpected; 22963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 22973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // collect result chain for each element 22983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int callNdx = 0; callNdx < m_numCalls; ++callNdx) 22993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry valueChain[callNdx] = intermediateResults[callNdx][valueNdx]; 23003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 23013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // check there exists a path from 0 to sumValue using each addition once 23023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // decompose cumulative results to addition operations (all additions positive => this works) 23033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 23043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::sort(valueChain.begin(), valueChain.end()); 23053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 23063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // validate chain 23073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!validateSortedAtomicRampAdditionValueChain(valueChain, sumValue, invalidOperationNdx, errorDelta, errorExpected)) 23083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 23093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() 23103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << tcu::TestLog::Message 23113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "Intermediate buffer error, at value index " << valueNdx << ", applied operation index " << invalidOperationNdx << ", value was increased by " << errorDelta << ", but expected " << errorExpected << ".\n" 23123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "Intermediate buffer contains invalid values. Values at index " << valueNdx << "\n" 23133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << tcu::TestLog::EndMessage; 23143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 23153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int logCallNdx = 0; logCallNdx < m_numCalls; ++logCallNdx) 23163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Value[" << logCallNdx << "] = " << intermediateResults[logCallNdx][valueNdx] << tcu::TestLog::EndMessage; 23173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Result = " << sumValue << tcu::TestLog::EndMessage; 23183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 23193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Buffer contents invalid"); 23203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return STOP; 23213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 23223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 23233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 23243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Intermediate buffers are valid." << tcu::TestLog::EndMessage; 23253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 23263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 23273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 23283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return STOP; 23293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 23303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 23313c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::string SSBOConcurrentAtomicCase::genComputeSource (void) const 23323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 23333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::ostringstream buf; 23343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 23353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "#version 310 es\n" 23363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n" 23373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "layout (binding = 1, std430) writeonly buffer IntermediateResults\n" 23383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "{\n" 23393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " highp uint values[" << m_workSize << "];\n" 23403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "} sb_ires;\n" 23413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "\n" 23423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "layout (binding = 2, std430) volatile buffer WorkBuffer\n" 23433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "{\n" 23443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " highp uint values[" << m_workSize << "];\n" 23453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "} sb_work;\n" 23463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "uniform highp uint u_atomicDelta;\n" 23473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "\n" 23483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "void main ()\n" 23493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "{\n" 23503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " highp uint invocationIndex = gl_GlobalInvocationID.x;\n" 23513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " sb_ires.values[invocationIndex] = atomicAdd(sb_work.values[invocationIndex], u_atomicDelta);\n" 23523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "}"; 23533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 23543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return buf.str(); 23553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 23563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 23573c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass ConcurrentAtomicCounterCase : public TestCase 23583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 23593c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 23603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 23613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ConcurrentAtomicCounterCase (Context& context, const char* name, const char* description, int numCalls, int workSize); 23623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ~ConcurrentAtomicCounterCase (void); 23633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 23643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void init (void); 23653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void deinit (void); 23663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IterateResult iterate (void); 23673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 23683c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate: 23693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::string genComputeSource (bool evenOdd) const; 23703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 23713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int m_numCalls; 23723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int m_workSize; 23733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glu::ShaderProgram* m_evenProgram; 23743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glu::ShaderProgram* m_oddProgram; 23753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deUint32 m_counterBuffer; 23763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deUint32 m_intermediateResultBuffer; 23773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 23783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 23793c827367444ee418f129b2c238299f49d3264554Jarkko PoyryConcurrentAtomicCounterCase::ConcurrentAtomicCounterCase (Context& context, const char* name, const char* description, int numCalls, int workSize) 23803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : TestCase (context, name, description) 23813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_numCalls (numCalls) 23823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_workSize (workSize) 23833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_evenProgram (DE_NULL) 23843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_oddProgram (DE_NULL) 23853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_counterBuffer (DE_NULL) 23863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_intermediateResultBuffer(DE_NULL) 23873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 23883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 23893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 23903c827367444ee418f129b2c238299f49d3264554Jarkko PoyryConcurrentAtomicCounterCase::~ConcurrentAtomicCounterCase (void) 23913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 23923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deinit(); 23933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 23943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 23953c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ConcurrentAtomicCounterCase::init (void) 23963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 23973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 23983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const std::vector<deUint32> zeroData (m_numCalls * m_workSize, 0); 23993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 24003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // gen buffer 24013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 24023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.genBuffers(1, &m_counterBuffer); 24033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindBuffer(GL_SHADER_STORAGE_BUFFER, m_counterBuffer); 24043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bufferData(GL_SHADER_STORAGE_BUFFER, sizeof(deUint32), &zeroData[0], GL_DYNAMIC_COPY); 24053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 24063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.genBuffers(1, &m_intermediateResultBuffer); 24073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindBuffer(GL_SHADER_STORAGE_BUFFER, m_intermediateResultBuffer); 24083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bufferData(GL_SHADER_STORAGE_BUFFER, sizeof(deUint32) * m_numCalls * m_workSize, &zeroData[0], GL_DYNAMIC_COPY); 24093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 24103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "gen buffers"); 24113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 24123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // gen programs 24133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 24143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 24153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const tcu::ScopedLogSection section(m_testCtx.getLog(), "EvenProgram", "Even program"); 24163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 24173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_evenProgram = new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources() << glu::ComputeSource(genComputeSource(true))); 24183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << *m_evenProgram; 24193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!m_evenProgram->isOk()) 24203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw tcu::TestError("could not build program"); 24213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 24223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 24233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const tcu::ScopedLogSection section(m_testCtx.getLog(), "OddProgram", "Odd program"); 24243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 24253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_oddProgram = new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources() << glu::ComputeSource(genComputeSource(false))); 24263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << *m_oddProgram; 24273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!m_oddProgram->isOk()) 24283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw tcu::TestError("could not build program"); 24293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 24303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 24313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 24323c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ConcurrentAtomicCounterCase::deinit (void) 24333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 24343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_counterBuffer) 24353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 24363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_context.getRenderContext().getFunctions().deleteBuffers(1, &m_counterBuffer); 24373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_counterBuffer = 0; 24383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 24393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_intermediateResultBuffer) 24403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 24413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_context.getRenderContext().getFunctions().deleteBuffers(1, &m_intermediateResultBuffer); 24423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_intermediateResultBuffer = 0; 24433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 24443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 24453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry delete m_evenProgram; 24463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_evenProgram = DE_NULL; 24473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 24483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry delete m_oddProgram; 24493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_oddProgram = DE_NULL; 24503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 24513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 24523c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTestCase::IterateResult ConcurrentAtomicCounterCase::iterate (void) 24533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 24543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 24553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 24563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // invoke program N times, each with a different delta 24573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 24583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int evenCallNdxLocation = gl.getUniformLocation(m_evenProgram->getProgram(), "u_callNdx"); 24593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int oddCallNdxLocation = gl.getUniformLocation(m_oddProgram->getProgram(), "u_callNdx"); 24603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 24613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() 24623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << tcu::TestLog::Message 24633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "Running shader pair (even & odd) " << m_numCalls << " times.\n" 24643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "Num groups = (" << m_workSize << ", 1, 1)\n" 24653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << tcu::TestLog::EndMessage; 24663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 24673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (evenCallNdxLocation == -1) 24683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw tcu::TestError("u_callNdx location was -1"); 24693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (oddCallNdxLocation == -1) 24703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw tcu::TestError("u_callNdx location was -1"); 24713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 24723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_intermediateResultBuffer); 24733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 2, m_counterBuffer); 24743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 24753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int callNdx = 0; callNdx < m_numCalls; ++callNdx) 24763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 24773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.useProgram(m_evenProgram->getProgram()); 24783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.uniform1ui(evenCallNdxLocation, (deUint32)callNdx); 24793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.dispatchCompute(m_workSize, 1, 1); 24803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 24813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.useProgram(m_oddProgram->getProgram()); 24823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.uniform1ui(oddCallNdxLocation, (deUint32)callNdx); 24833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.dispatchCompute(m_workSize, 1, 1); 24843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 24853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 24863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "post dispatch"); 24873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 24883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 24893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Verify result 24903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 24913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deUint32 result; 24923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 24933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Verifying work buffer, it should be " << m_numCalls*m_workSize << tcu::TestLog::EndMessage; 24943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 24953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindBuffer(GL_ATOMIC_COUNTER_BUFFER, m_counterBuffer); 24963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry result = readBufferUint32(gl, GL_ATOMIC_COUNTER_BUFFER); 24973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 24983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if ((int)result != m_numCalls*m_workSize) 24993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 25003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() 25013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << tcu::TestLog::Message 25023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "Counter buffer error, expected value " << (m_numCalls*m_workSize) << ", got " << result << "\n" 25033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << tcu::TestLog::EndMessage; 25043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 25053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Buffer contents invalid"); 25063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return STOP; 25073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 25083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 25093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Counter buffer is valid." << tcu::TestLog::EndMessage; 25103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 25113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 25123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // verify steps 25133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 25143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::vector<deUint32> intermediateResults; 25153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 25163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Verifying intermediate results. " << tcu::TestLog::EndMessage; 25173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 25183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // collect results 25193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 25203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindBuffer(GL_SHADER_STORAGE_BUFFER, m_intermediateResultBuffer); 25213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry readBuffer(gl, GL_SHADER_STORAGE_BUFFER, m_numCalls * m_workSize, intermediateResults); 25223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 25233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // verify values 25243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 25253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::sort(intermediateResults.begin(), intermediateResults.end()); 25263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 25273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int valueNdx = 0; valueNdx < m_workSize * m_numCalls; ++valueNdx) 25283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 25293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if ((int)intermediateResults[valueNdx] != valueNdx) 25303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 25313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() 25323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << tcu::TestLog::Message 25333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "Intermediate buffer error, at value index " << valueNdx << ", expected " << valueNdx << ", got " << intermediateResults[valueNdx] << ".\n" 25343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "Intermediate buffer contains invalid values. Intermediate results:\n" 25353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << tcu::TestLog::EndMessage; 25363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 25373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int logCallNdx = 0; logCallNdx < m_workSize * m_numCalls; ++logCallNdx) 25383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Value[" << logCallNdx << "] = " << intermediateResults[logCallNdx] << tcu::TestLog::EndMessage; 25393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 25403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Buffer contents invalid"); 25413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return STOP; 25423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 25433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 25443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 25453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Intermediate buffers are valid." << tcu::TestLog::EndMessage; 25463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 25473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 25483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 25493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return STOP; 25503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 25513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 25523c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::string ConcurrentAtomicCounterCase::genComputeSource (bool evenOdd) const 25533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 25543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::ostringstream buf; 25553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 25563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "#version 310 es\n" 25573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n" 25583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "layout (binding = 1, std430) writeonly buffer IntermediateResults\n" 25593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "{\n" 25603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " highp uint values[" << m_workSize * m_numCalls << "];\n" 25613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "} sb_ires;\n" 25623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "\n" 25633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "layout (binding = 2, offset = 0) uniform atomic_uint u_counter;\n" 25643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "uniform highp uint u_callNdx;\n" 25653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "\n" 25663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "void main ()\n" 25673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "{\n" 25683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " highp uint dataNdx = u_callNdx * " << m_workSize << "u + gl_GlobalInvocationID.x;\n" 25693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " if ((dataNdx % 2u) == " << ((evenOdd) ? (0) : (1)) << "u)\n" 25703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " sb_ires.values[dataNdx] = atomicCounterIncrement(u_counter);\n" 25713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "}"; 25723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 25733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return buf.str(); 25743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 25753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 25763c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass ConcurrentImageAtomicCase : public TestCase 25773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 25783c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 25793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 25803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ConcurrentImageAtomicCase (Context& context, const char* name, const char* description, int numCalls, int workSize); 25813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ~ConcurrentImageAtomicCase (void); 25823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 25833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void init (void); 25843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void deinit (void); 25853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IterateResult iterate (void); 25863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 25873c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate: 25883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void readWorkImage (std::vector<deUint32>& result); 25893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 25903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::string genComputeSource (void) const; 25913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::string genImageReadSource (void) const; 25923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::string genImageClearSource (void) const; 25933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 25943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int m_numCalls; 25953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int m_workSize; 25963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glu::ShaderProgram* m_program; 25973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glu::ShaderProgram* m_imageReadProgram; 25983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glu::ShaderProgram* m_imageClearProgram; 25993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deUint32 m_imageID; 26003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::vector<deUint32> m_intermediateResultBuffers; 26013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 26023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 26033c827367444ee418f129b2c238299f49d3264554Jarkko PoyryConcurrentImageAtomicCase::ConcurrentImageAtomicCase (Context& context, const char* name, const char* description, int numCalls, int workSize) 26043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : TestCase (context, name, description) 26053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_numCalls (numCalls) 26063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_workSize (workSize) 26073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_program (DE_NULL) 26083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_imageReadProgram (DE_NULL) 26093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_imageClearProgram (DE_NULL) 26103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_imageID (DE_NULL) 26113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 26123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 26133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 26143c827367444ee418f129b2c238299f49d3264554Jarkko PoyryConcurrentImageAtomicCase::~ConcurrentImageAtomicCase (void) 26153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 26163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deinit(); 26173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 26183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 26193c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ConcurrentImageAtomicCase::init (void) 26203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 26213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 26223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::vector<deUint32> zeroData (m_workSize * m_workSize, 0); 26233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 26243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!m_context.getContextInfo().isExtensionSupported("GL_OES_shader_image_atomic")) 26253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw tcu::NotSupportedError("Test requires GL_OES_shader_image_atomic"); 26263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 26273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // gen image 26283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 26293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.genTextures(1, &m_imageID); 26303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindTexture(GL_TEXTURE_2D, m_imageID); 26313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.texStorage2D(GL_TEXTURE_2D, 1, GL_R32UI, m_workSize, m_workSize); 26328852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 26338852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 26343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "gen tex"); 26353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 26363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // gen buffers 26373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 26383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < m_numCalls; ++ndx) 26393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 26403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deUint32 buffer = 0; 26413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 26423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.genBuffers(1, &buffer); 26433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindBuffer(GL_SHADER_STORAGE_BUFFER, buffer); 26443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bufferData(GL_SHADER_STORAGE_BUFFER, sizeof(deUint32) * m_workSize * m_workSize, &zeroData[0], GL_DYNAMIC_COPY); 26453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 26463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_intermediateResultBuffers.push_back(buffer); 26473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "gen buffers"); 26483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 26493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 26503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // gen programs 26513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 26523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_program = new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources() << glu::ComputeSource(genComputeSource())); 26533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << *m_program; 26543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!m_program->isOk()) 26553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw tcu::TestError("could not build program"); 26563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 26573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_imageReadProgram = new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources() << glu::ComputeSource(genImageReadSource())); 26583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!m_imageReadProgram->isOk()) 26593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 26603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const tcu::ScopedLogSection section(m_testCtx.getLog(), "ImageReadProgram", "Image read program"); 26613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 26623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << *m_imageReadProgram; 26633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw tcu::TestError("could not build program"); 26643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 26653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 26663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_imageClearProgram = new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources() << glu::ComputeSource(genImageClearSource())); 26673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!m_imageClearProgram->isOk()) 26683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 26693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const tcu::ScopedLogSection section(m_testCtx.getLog(), "ImageClearProgram", "Image read program"); 26703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 26713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << *m_imageClearProgram; 26723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw tcu::TestError("could not build program"); 26733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 26743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 26753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 26763c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ConcurrentImageAtomicCase::deinit (void) 26773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 26783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_imageID) 26793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 26803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_context.getRenderContext().getFunctions().deleteTextures(1, &m_imageID); 26813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_imageID = 0; 26823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 26833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 26843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < (int)m_intermediateResultBuffers.size(); ++ndx) 26853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_context.getRenderContext().getFunctions().deleteBuffers(1, &m_intermediateResultBuffers[ndx]); 26863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_intermediateResultBuffers.clear(); 26873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 26883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry delete m_program; 26893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_program = DE_NULL; 26903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 26913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry delete m_imageReadProgram; 26923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_imageReadProgram = DE_NULL; 26933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 26943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry delete m_imageClearProgram; 26953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_imageClearProgram = DE_NULL; 26963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 26973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 26983c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTestCase::IterateResult ConcurrentImageAtomicCase::iterate (void) 26993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 27003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 27013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const deUint32 sumValue = (deUint32)(m_numCalls * (m_numCalls + 1) / 2); 27023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::vector<int> deltas; 27033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 27043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // generate unique deltas 27053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry generateShuffledRamp(m_numCalls, deltas); 27063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 27073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // clear image 27083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 27093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Clearing image contents" << tcu::TestLog::EndMessage; 27103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 27113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.useProgram(m_imageClearProgram->getProgram()); 27123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindImageTexture(2, m_imageID, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_R32UI); 27133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.dispatchCompute(m_workSize, m_workSize, 1); 27143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.memoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT); 27153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 27163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "clear"); 27173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 27183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 27193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // invoke program N times, each with a different delta 27203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 27213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int deltaLocation = gl.getUniformLocation(m_program->getProgram(), "u_atomicDelta"); 27223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 27233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() 27243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << tcu::TestLog::Message 27253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "Running shader " << m_numCalls << " times.\n" 27263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "Num groups = (" << m_workSize << ", " << m_workSize << ", 1)\n" 27273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "Setting u_atomicDelta to a unique value for each call.\n" 27283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << tcu::TestLog::EndMessage; 27293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 27303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (deltaLocation == -1) 27313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw tcu::TestError("u_atomicDelta location was -1"); 27323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 27333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.useProgram(m_program->getProgram()); 27343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindImageTexture(2, m_imageID, 0, GL_FALSE, 0, GL_READ_WRITE, GL_R32UI); 27353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 27363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int callNdx = 0; callNdx < m_numCalls; ++callNdx) 27373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 27383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() 27393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << tcu::TestLog::Message 27403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "Call " << callNdx << ": u_atomicDelta = " << deltas[callNdx] 27413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << tcu::TestLog::EndMessage; 27423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 27433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.uniform1ui(deltaLocation, deltas[callNdx]); 27443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_intermediateResultBuffers[callNdx]); 27453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.dispatchCompute(m_workSize, m_workSize, 1); 27463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 27473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 27483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "post dispatch"); 27493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 27503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 27513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Verify result 27523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 27533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::vector<deUint32> result; 27543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 27553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Verifying work image, it should be filled with value " << sumValue << tcu::TestLog::EndMessage; 27563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 27573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry readWorkImage(result); 27583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 27593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < m_workSize * m_workSize; ++ndx) 27603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 27613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (result[ndx] != sumValue) 27623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 27633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() 27643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << tcu::TestLog::Message 27653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "Work image error, at index (" << ndx % m_workSize << ", " << ndx / m_workSize << ") expected value " << (sumValue) << ", got " << result[ndx] << "\n" 27663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "Work image contains invalid values." 27673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << tcu::TestLog::EndMessage; 27683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 27693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image contents invalid"); 27703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return STOP; 27713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 27723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 27733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 27743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Work image contents are valid." << tcu::TestLog::EndMessage; 27753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 27763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 27773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // verify steps 27783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 27793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::vector<std::vector<deUint32> > intermediateResults (m_numCalls); 27803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::vector<deUint32> valueChain (m_numCalls); 27813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::vector<deUint32> chainDelta (m_numCalls); 27823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 27833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Verifying intermediate results. " << tcu::TestLog::EndMessage; 27843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 27853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // collect results 27863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 27873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int callNdx = 0; callNdx < m_numCalls; ++callNdx) 27883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 27893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindBuffer(GL_SHADER_STORAGE_BUFFER, m_intermediateResultBuffers[callNdx]); 27903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry readBuffer(gl, GL_SHADER_STORAGE_BUFFER, m_workSize * m_workSize, intermediateResults[callNdx]); 27913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 27923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 27933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // verify values 27943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 27953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int valueNdx = 0; valueNdx < m_workSize; ++valueNdx) 27963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 27973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int invalidOperationNdx; 27983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deUint32 errorDelta; 27993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deUint32 errorExpected; 28003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 28013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // collect result chain for each element 28023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int callNdx = 0; callNdx < m_numCalls; ++callNdx) 28033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry valueChain[callNdx] = intermediateResults[callNdx][valueNdx]; 28043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 28053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // check there exists a path from 0 to sumValue using each addition once 28063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // decompose cumulative results to addition operations (all additions positive => this works) 28073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 28083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::sort(valueChain.begin(), valueChain.end()); 28093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 28103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int callNdx = 0; callNdx < m_numCalls; ++callNdx) 28113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry chainDelta[callNdx] = ((callNdx + 1 == m_numCalls) ? (sumValue) : (valueChain[callNdx+1])) - valueChain[callNdx]; 28123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 28133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // chainDelta contains now the actual additions applied to the value 28143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::sort(chainDelta.begin(), chainDelta.end()); 28153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 28163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // validate chain 28173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!validateSortedAtomicRampAdditionValueChain(valueChain, sumValue, invalidOperationNdx, errorDelta, errorExpected)) 28183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 28193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() 28203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << tcu::TestLog::Message 28213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "Intermediate buffer error, at index (" << valueNdx % m_workSize << ", " << valueNdx / m_workSize << "), applied operation index " 28223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << invalidOperationNdx << ", value was increased by " << errorDelta << ", but expected " << errorExpected << ".\n" 28233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "Intermediate buffer contains invalid values. Values at index (" << valueNdx % m_workSize << ", " << valueNdx / m_workSize << ")\n" 28243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << tcu::TestLog::EndMessage; 28253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 28263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int logCallNdx = 0; logCallNdx < m_numCalls; ++logCallNdx) 28273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Value[" << logCallNdx << "] = " << intermediateResults[logCallNdx][valueNdx] << tcu::TestLog::EndMessage; 28283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Result = " << sumValue << tcu::TestLog::EndMessage; 28293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 28303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Buffer contents invalid"); 28313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return STOP; 28323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 28333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 28343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 28353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Intermediate buffers are valid." << tcu::TestLog::EndMessage; 28363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 28373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 28383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 28393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return STOP; 28403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 28413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 28423c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ConcurrentImageAtomicCase::readWorkImage (std::vector<deUint32>& result) 28433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 28443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 28453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glu::Buffer resultBuffer (m_context.getRenderContext()); 28463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 28473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Read image to an ssbo 28483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 28493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 28503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const std::vector<deUint32> zeroData(m_workSize*m_workSize, 0); 28513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 28523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindBuffer(GL_SHADER_STORAGE_BUFFER, *resultBuffer); 28533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bufferData(GL_SHADER_STORAGE_BUFFER, (int)(sizeof(deUint32) * m_workSize * m_workSize), &zeroData[0], GL_DYNAMIC_COPY); 28543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 28553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.memoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT); 28563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.useProgram(m_imageReadProgram->getProgram()); 28573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 28583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, *resultBuffer); 28593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindImageTexture(2, m_imageID, 0, GL_FALSE, 0, GL_READ_ONLY, GL_R32UI); 28603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.dispatchCompute(m_workSize, m_workSize, 1); 28613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 28623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "read"); 28633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 28643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 28653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Read ssbo 28663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 28673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const void* ptr = gl.mapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, (int)(sizeof(deUint32) * m_workSize * m_workSize), GL_MAP_READ_BIT); 28683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "map"); 28693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 28703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!ptr) 28713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw tcu::TestError("mapBufferRange returned NULL"); 28723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 28733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry result.resize(m_workSize * m_workSize); 28743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry memcpy(&result[0], ptr, sizeof(deUint32) * m_workSize * m_workSize); 28753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 28763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (gl.unmapBuffer(GL_SHADER_STORAGE_BUFFER) == GL_FALSE) 28773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw tcu::TestError("unmapBuffer returned false"); 28783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 28793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 28803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 28813c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::string ConcurrentImageAtomicCase::genComputeSource (void) const 28823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 28833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::ostringstream buf; 28843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 28853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "#version 310 es\n" 28863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "#extension GL_OES_shader_image_atomic : require\n" 28873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "\n" 28883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n" 28893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "layout (binding = 1, std430) writeonly buffer IntermediateResults\n" 28903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "{\n" 28913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " highp uint values[" << m_workSize * m_workSize << "];\n" 28923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "} sb_ires;\n" 28933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "\n" 28948852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry << "layout (binding = 2, r32ui) volatile uniform highp uimage2D u_workImage;\n" 28953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "uniform highp uint u_atomicDelta;\n" 28963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "\n" 28973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "void main ()\n" 28983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "{\n" 28993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " highp uint invocationIndex = gl_GlobalInvocationID.x + gl_GlobalInvocationID.y * uint(" << m_workSize <<");\n" 29003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " sb_ires.values[invocationIndex] = imageAtomicAdd(u_workImage, ivec2(gl_GlobalInvocationID.xy), u_atomicDelta);\n" 29013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "}"; 29023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 29033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return buf.str(); 29043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 29053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 29063c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::string ConcurrentImageAtomicCase::genImageReadSource (void) const 29073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 29083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::ostringstream buf; 29093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 29103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "#version 310 es\n" 29113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "\n" 29123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n" 29133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "layout (binding = 1, std430) writeonly buffer ImageValues\n" 29143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "{\n" 29153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " highp uint values[" << m_workSize * m_workSize << "];\n" 29163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "} sb_res;\n" 29173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "\n" 29188852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry << "layout (binding = 2, r32ui) readonly uniform highp uimage2D u_workImage;\n" 29193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "\n" 29203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "void main ()\n" 29213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "{\n" 29223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " highp uint invocationIndex = gl_GlobalInvocationID.x + gl_GlobalInvocationID.y * uint(" << m_workSize <<");\n" 29233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " sb_res.values[invocationIndex] = imageLoad(u_workImage, ivec2(gl_GlobalInvocationID.xy)).x;\n" 29243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "}"; 29253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 29263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return buf.str(); 29273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 29283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 29293c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::string ConcurrentImageAtomicCase::genImageClearSource (void) const 29303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 29313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::ostringstream buf; 29323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 29333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "#version 310 es\n" 29343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "\n" 29353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n" 29368852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry << "layout (binding = 2, r32ui) writeonly uniform highp uimage2D u_workImage;\n" 29373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "\n" 29383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "void main ()\n" 29393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "{\n" 29403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " imageStore(u_workImage, ivec2(gl_GlobalInvocationID.xy), uvec4(0, 0, 0, 0));\n" 29413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "}"; 29423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 29433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return buf.str(); 29443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 29453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 29463c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass ConcurrentSSBOAtomicCounterMixedCase : public TestCase 29473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 29483c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 29493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ConcurrentSSBOAtomicCounterMixedCase (Context& context, const char* name, const char* description, int numCalls, int workSize); 29503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ~ConcurrentSSBOAtomicCounterMixedCase (void); 29513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 29523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void init (void); 29533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void deinit (void); 29543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IterateResult iterate (void); 29553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 29563c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate: 29573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::string genSSBOComputeSource (void) const; 29583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::string genAtomicCounterComputeSource (void) const; 29593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 29603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int m_numCalls; 29613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int m_workSize; 29623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deUint32 m_bufferID; 29633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glu::ShaderProgram* m_ssboAtomicProgram; 29643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glu::ShaderProgram* m_atomicCounterProgram; 29653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 29663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 29673c827367444ee418f129b2c238299f49d3264554Jarkko PoyryConcurrentSSBOAtomicCounterMixedCase::ConcurrentSSBOAtomicCounterMixedCase (Context& context, const char* name, const char* description, int numCalls, int workSize) 29683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : TestCase (context, name, description) 29693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_numCalls (numCalls) 29703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_workSize (workSize) 29713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_bufferID (DE_NULL) 29723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_ssboAtomicProgram (DE_NULL) 29733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_atomicCounterProgram (DE_NULL) 29743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 29753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // SSBO atomic XORs cancel out 29763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT((workSize * numCalls) % (16 * 2) == 0); 29773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 29783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 29793c827367444ee418f129b2c238299f49d3264554Jarkko PoyryConcurrentSSBOAtomicCounterMixedCase::~ConcurrentSSBOAtomicCounterMixedCase (void) 29803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 29813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deinit(); 29823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 29833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 29843c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ConcurrentSSBOAtomicCounterMixedCase::init (void) 29853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 29863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 29873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const deUint32 zeroBuf[2] = { 0, 0 }; 29883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 29893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // gen buffer 29903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 29913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.genBuffers(1, &m_bufferID); 29923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindBuffer(GL_SHADER_STORAGE_BUFFER, m_bufferID); 29933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bufferData(GL_SHADER_STORAGE_BUFFER, (int)(sizeof(deUint32) * 2), zeroBuf, GL_DYNAMIC_COPY); 29943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 29953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "gen buffers"); 29963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 29973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // gen programs 29983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 29993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 30003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const tcu::ScopedLogSection section(m_testCtx.getLog(), "SSBOProgram", "SSBO atomic program"); 30013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 30023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_ssboAtomicProgram = new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources() << glu::ComputeSource(genSSBOComputeSource())); 30033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << *m_ssboAtomicProgram; 30043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!m_ssboAtomicProgram->isOk()) 30053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw tcu::TestError("could not build program"); 30063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 30073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 30083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const tcu::ScopedLogSection section(m_testCtx.getLog(), "AtomicCounterProgram", "Atomic counter program"); 30093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 30103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_atomicCounterProgram = new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources() << glu::ComputeSource(genAtomicCounterComputeSource())); 30113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << *m_atomicCounterProgram; 30123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!m_atomicCounterProgram->isOk()) 30133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw tcu::TestError("could not build program"); 30143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 30153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 30163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 30173c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ConcurrentSSBOAtomicCounterMixedCase::deinit (void) 30183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 30193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_bufferID) 30203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 30213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_context.getRenderContext().getFunctions().deleteBuffers(1, &m_bufferID); 30223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_bufferID = 0; 30233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 30243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 30253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry delete m_ssboAtomicProgram; 30263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_ssboAtomicProgram = DE_NULL; 30273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 30283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry delete m_atomicCounterProgram; 30293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_atomicCounterProgram = DE_NULL; 30303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 30313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 30323c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTestCase::IterateResult ConcurrentSSBOAtomicCounterMixedCase::iterate (void) 30333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 30343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 30353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 30363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Testing atomic counters and SSBO atomic operations with both backed by the same buffer." << tcu::TestLog::EndMessage; 30373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 30383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // invoke programs N times 30393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 30403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() 30413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << tcu::TestLog::Message 30423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "Running SSBO atomic program and atomic counter program " << m_numCalls << " times. (interleaved)\n" 30433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "Num groups = (" << m_workSize << ", 1, 1)\n" 30443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << tcu::TestLog::EndMessage; 30453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 30463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_bufferID); 30473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 2, m_bufferID); 30483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 30493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int callNdx = 0; callNdx < m_numCalls; ++callNdx) 30503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 30513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.useProgram(m_atomicCounterProgram->getProgram()); 30523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.dispatchCompute(m_workSize, 1, 1); 30533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 30543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.useProgram(m_ssboAtomicProgram->getProgram()); 30553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.dispatchCompute(m_workSize, 1, 1); 30563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 30573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 30583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "post dispatch"); 30593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 30603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 30613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Verify result 30623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 30633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deUint32 result; 30643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 30653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // XORs cancel out, only addition is left 30663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Verifying work buffer, it should be " << m_numCalls*m_workSize << tcu::TestLog::EndMessage; 30673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 30683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindBuffer(GL_ATOMIC_COUNTER_BUFFER, m_bufferID); 30693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry result = readBufferUint32(gl, GL_ATOMIC_COUNTER_BUFFER); 30703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 30713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if ((int)result != m_numCalls*m_workSize) 30723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 30733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() 30743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << tcu::TestLog::Message 30753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "Buffer value error, expected value " << (m_numCalls*m_workSize) << ", got " << result << "\n" 30763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << tcu::TestLog::EndMessage; 30773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 30783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Buffer contents invalid"); 30793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return STOP; 30803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 30813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 30823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Buffer is valid." << tcu::TestLog::EndMessage; 30833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 30843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 30853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 30863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return STOP; 30873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 30883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 30893c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::string ConcurrentSSBOAtomicCounterMixedCase::genSSBOComputeSource (void) const 30903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 30913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::ostringstream buf; 30923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 30933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "#version 310 es\n" 30943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n" 30953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "layout (binding = 1, std430) volatile buffer WorkBuffer\n" 30963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "{\n" 30973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " highp uint targetValue;\n" 30983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " highp uint dummy;\n" 30993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "} sb_work;\n" 31003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "\n" 31013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "void main ()\n" 31023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "{\n" 31033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " // flip high bits\n" 31043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " highp uint mask = uint(1) << (16u + (gl_GlobalInvocationID.x % 16u));\n" 31053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " sb_work.dummy = atomicXor(sb_work.targetValue, mask);\n" 31063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "}"; 31073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 31083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return buf.str(); 31093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 31103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 31113c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::string ConcurrentSSBOAtomicCounterMixedCase::genAtomicCounterComputeSource (void) const 31123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 31133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::ostringstream buf; 31143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 31153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "#version 310 es\n" 31163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n" 31173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "\n" 31183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "layout (binding = 2, offset = 0) uniform atomic_uint u_counter;\n" 31193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "\n" 31203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "void main ()\n" 31213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "{\n" 31223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " atomicCounterIncrement(u_counter);\n" 31233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "}"; 31243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 31253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return buf.str(); 31263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 31273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 31283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // anonymous 31293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 31303c827367444ee418f129b2c238299f49d3264554Jarkko PoyrySynchronizationTests::SynchronizationTests (Context& context) 31313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : TestCaseGroup(context, "synchronization", "Synchronization tests") 31323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 31333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 31343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 31353c827367444ee418f129b2c238299f49d3264554Jarkko PoyrySynchronizationTests::~SynchronizationTests (void) 31363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 31373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 31383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 31393c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid SynchronizationTests::init (void) 31403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 31413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcu::TestCaseGroup* const inInvocationGroup = new tcu::TestCaseGroup(m_testCtx, "in_invocation", "Test intra-invocation synchronization"); 31423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcu::TestCaseGroup* const interInvocationGroup = new tcu::TestCaseGroup(m_testCtx, "inter_invocation", "Test inter-invocation synchronization"); 31433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcu::TestCaseGroup* const interCallGroup = new tcu::TestCaseGroup(m_testCtx, "inter_call", "Test inter-call synchronization"); 31443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 31453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry addChild(inInvocationGroup); 31463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry addChild(interInvocationGroup); 31473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry addChild(interCallGroup); 31483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 31493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // .in_invocation & .inter_invocation 31503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 31513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static const struct CaseConfig 31523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 31533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const char* namePrefix; 31543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const InterInvocationTestCase::StorageType storage; 31553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int flags; 31563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } configs[] = 31573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 31583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { "image", InterInvocationTestCase::STORAGE_IMAGE, 0 }, 31593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { "image_atomic", InterInvocationTestCase::STORAGE_IMAGE, InterInvocationTestCase::FLAG_ATOMIC }, 31603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { "ssbo", InterInvocationTestCase::STORAGE_BUFFER, 0 }, 31613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { "ssbo_atomic", InterInvocationTestCase::STORAGE_BUFFER, InterInvocationTestCase::FLAG_ATOMIC }, 31623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 31633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 31643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int groupNdx = 0; groupNdx < 2; ++groupNdx) 31653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 31663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcu::TestCaseGroup* const targetGroup = (groupNdx == 0) ? (inInvocationGroup) : (interInvocationGroup); 31673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int extraFlags = (groupNdx == 0) ? (0) : (InterInvocationTestCase::FLAG_IN_GROUP); 31683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 31693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int configNdx = 0; configNdx < DE_LENGTH_OF_ARRAY(configs); ++configNdx) 31703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 31713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const char* const target = (configs[configNdx].storage == InterInvocationTestCase::STORAGE_BUFFER) ? ("buffer") : ("image"); 31723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 31733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry targetGroup->addChild(new InvocationWriteReadCase(m_context, 31743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry (std::string(configs[configNdx].namePrefix) + "_write_read").c_str(), 31753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry (std::string("Write to ") + target + " and read it").c_str(), 31763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry configs[configNdx].storage, 31773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry configs[configNdx].flags | extraFlags)); 31783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 31793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry targetGroup->addChild(new InvocationReadWriteCase(m_context, 31803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry (std::string(configs[configNdx].namePrefix) + "_read_write").c_str(), 31813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry (std::string("Read form ") + target + " and then write to it").c_str(), 31823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry configs[configNdx].storage, 31833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry configs[configNdx].flags | extraFlags)); 31843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 31853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry targetGroup->addChild(new InvocationOverWriteCase(m_context, 31863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry (std::string(configs[configNdx].namePrefix) + "_overwrite").c_str(), 31873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry (std::string("Write to ") + target + " twice and read it").c_str(), 31883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry configs[configNdx].storage, 31893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry configs[configNdx].flags | extraFlags)); 31903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 31913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry targetGroup->addChild(new InvocationAliasWriteCase(m_context, 31923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry (std::string(configs[configNdx].namePrefix) + "_alias_write").c_str(), 31933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry (std::string("Write to aliasing ") + target + " and read it").c_str(), 31943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry InvocationAliasWriteCase::TYPE_WRITE, 31953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry configs[configNdx].storage, 31963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry configs[configNdx].flags | extraFlags)); 31973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 31983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry targetGroup->addChild(new InvocationAliasWriteCase(m_context, 31993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry (std::string(configs[configNdx].namePrefix) + "_alias_overwrite").c_str(), 32003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry (std::string("Write to aliasing ") + target + "s and read it").c_str(), 32013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry InvocationAliasWriteCase::TYPE_OVERWRITE, 32023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry configs[configNdx].storage, 32033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry configs[configNdx].flags | extraFlags)); 32043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 32053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 32063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 32073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 32083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // .inter_call 32093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 32103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcu::TestCaseGroup* const withBarrierGroup = new tcu::TestCaseGroup(m_testCtx, "with_memory_barrier", "Synchronize with memory barrier"); 32113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcu::TestCaseGroup* const withoutBarrierGroup = new tcu::TestCaseGroup(m_testCtx, "without_memory_barrier", "Synchronize without memory barrier"); 32123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 32133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry interCallGroup->addChild(withBarrierGroup); 32143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry interCallGroup->addChild(withoutBarrierGroup); 32153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 32163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // .with_memory_barrier 32173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 32183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static const struct CaseConfig 32193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 32203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const char* namePrefix; 32213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const InterCallTestCase::StorageType storage; 32223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int flags; 32233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } configs[] = 32243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 32253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { "image", InterCallTestCase::STORAGE_IMAGE, 0 }, 32263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { "image_atomic", InterCallTestCase::STORAGE_IMAGE, InterCallTestCase::FLAG_USE_ATOMIC | InterCallTestCase::FLAG_USE_INT }, 32273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { "ssbo", InterCallTestCase::STORAGE_BUFFER, 0 }, 32283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { "ssbo_atomic", InterCallTestCase::STORAGE_BUFFER, InterCallTestCase::FLAG_USE_ATOMIC | InterCallTestCase::FLAG_USE_INT }, 32293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 32303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 32313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int seed0 = 123; 32323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int seed1 = 457; 32333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 32343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int configNdx = 0; configNdx < DE_LENGTH_OF_ARRAY(configs); ++configNdx) 32353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 32363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const char* const target = (configs[configNdx].storage == InterCallTestCase::STORAGE_BUFFER) ? ("buffer") : ("image"); 32373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 32383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry withBarrierGroup->addChild(new InterCallTestCase(m_context, 32393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry (std::string(configs[configNdx].namePrefix) + "_write_read").c_str(), 32403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry (std::string("Write to ") + target + " and read it").c_str(), 32413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry configs[configNdx].storage, 32423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry configs[configNdx].flags, 32433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry InterCallOperations() 32443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << op::WriteData::Generate(1, seed0) 32453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << op::Barrier() 32463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << op::ReadData::Generate(1, seed0))); 32473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 32483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry withBarrierGroup->addChild(new InterCallTestCase(m_context, 32493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry (std::string(configs[configNdx].namePrefix) + "_read_write").c_str(), 32503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry (std::string("Read from ") + target + " and then write to it").c_str(), 32513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry configs[configNdx].storage, 32523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry configs[configNdx].flags, 32533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry InterCallOperations() 32543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << op::ReadZeroData::Generate(1) 32553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << op::Barrier() 32563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << op::WriteData::Generate(1, seed0))); 32573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 32583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry withBarrierGroup->addChild(new InterCallTestCase(m_context, 32593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry (std::string(configs[configNdx].namePrefix) + "_overwrite").c_str(), 32603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry (std::string("Write to ") + target + " twice and read it").c_str(), 32613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry configs[configNdx].storage, 32623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry configs[configNdx].flags, 32633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry InterCallOperations() 32643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << op::WriteData::Generate(1, seed0) 32653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << op::Barrier() 32663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << op::WriteData::Generate(1, seed1) 32673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << op::Barrier() 32683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << op::ReadData::Generate(1, seed1))); 32693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 32703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry withBarrierGroup->addChild(new InterCallTestCase(m_context, 32713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry (std::string(configs[configNdx].namePrefix) + "_multiple_write_read").c_str(), 32723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry (std::string("Write to multiple ") + target + "s and read them").c_str(), 32733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry configs[configNdx].storage, 32743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry configs[configNdx].flags, 32753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry InterCallOperations() 32763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << op::WriteData::Generate(1, seed0) 32773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << op::WriteData::Generate(2, seed1) 32783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << op::Barrier() 32793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << op::ReadMultipleData::Generate(1, seed0, 2, seed1))); 32803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 32813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry withBarrierGroup->addChild(new InterCallTestCase(m_context, 32823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry (std::string(configs[configNdx].namePrefix) + "_multiple_interleaved_write_read").c_str(), 32833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry (std::string("Write to same ") + target + " in multiple calls and read it").c_str(), 32843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry configs[configNdx].storage, 32853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry configs[configNdx].flags, 32863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry InterCallOperations() 32873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << op::WriteDataInterleaved::Generate(1, seed0, true) 32883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << op::WriteDataInterleaved::Generate(1, seed1, false) 32893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << op::Barrier() 32903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << op::ReadDataInterleaved::Generate(1, seed0, seed1))); 32913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 32923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry withBarrierGroup->addChild(new InterCallTestCase(m_context, 32933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry (std::string(configs[configNdx].namePrefix) + "_multiple_unrelated_write_read_ordered").c_str(), 32943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry (std::string("Two unrelated ") + target + " write-reads").c_str(), 32953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry configs[configNdx].storage, 32963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry configs[configNdx].flags, 32973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry InterCallOperations() 32983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << op::WriteData::Generate(1, seed0) 32993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << op::WriteData::Generate(2, seed1) 33003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << op::Barrier() 33013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << op::ReadData::Generate(1, seed0) 33023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << op::ReadData::Generate(2, seed1))); 33033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 33043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry withBarrierGroup->addChild(new InterCallTestCase(m_context, 33053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry (std::string(configs[configNdx].namePrefix) + "_multiple_unrelated_write_read_non_ordered").c_str(), 33063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry (std::string("Two unrelated ") + target + " write-reads").c_str(), 33073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry configs[configNdx].storage, 33083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry configs[configNdx].flags, 33093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry InterCallOperations() 33103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << op::WriteData::Generate(1, seed0) 33113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << op::WriteData::Generate(2, seed1) 33123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << op::Barrier() 33133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << op::ReadData::Generate(2, seed1) 33143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << op::ReadData::Generate(1, seed0))); 33153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 33163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 33173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // .without_memory_barrier 33183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 33193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry struct InvocationConfig 33203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 33213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const char* name; 33223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int count; 33233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 33243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 33253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static const InvocationConfig ssboInvocations[] = 33263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 33273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { "1k", 1024 }, 33283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { "4k", 4096 }, 33293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { "32k", 32768 }, 33303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 33313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static const InvocationConfig imageInvocations[] = 33323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 33333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { "8x8", 8 }, 33343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { "32x32", 32 }, 33353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { "128x128", 128 }, 33363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 33373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static const InvocationConfig counterInvocations[] = 33383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 33393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { "32", 32 }, 33403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { "128", 128 }, 33413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { "1k", 1024 }, 33423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 33433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static const int callCounts[] = { 2, 5, 100 }; 33443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 33453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int invocationNdx = 0; invocationNdx < DE_LENGTH_OF_ARRAY(ssboInvocations); ++invocationNdx) 33463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int callCountNdx = 0; callCountNdx < DE_LENGTH_OF_ARRAY(callCounts); ++callCountNdx) 33473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry withoutBarrierGroup->addChild(new SSBOConcurrentAtomicCase(m_context, (std::string("ssbo_atomic_dispatch_") + de::toString(callCounts[callCountNdx]) + "_calls_" + ssboInvocations[invocationNdx].name + "_invocations").c_str(), "", callCounts[callCountNdx], ssboInvocations[invocationNdx].count)); 33483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 33493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int invocationNdx = 0; invocationNdx < DE_LENGTH_OF_ARRAY(imageInvocations); ++invocationNdx) 33503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int callCountNdx = 0; callCountNdx < DE_LENGTH_OF_ARRAY(callCounts); ++callCountNdx) 33513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry withoutBarrierGroup->addChild(new ConcurrentImageAtomicCase(m_context, (std::string("image_atomic_dispatch_") + de::toString(callCounts[callCountNdx]) + "_calls_" + imageInvocations[invocationNdx].name + "_invocations").c_str(), "", callCounts[callCountNdx], imageInvocations[invocationNdx].count)); 33523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 33533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int invocationNdx = 0; invocationNdx < DE_LENGTH_OF_ARRAY(counterInvocations); ++invocationNdx) 33543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int callCountNdx = 0; callCountNdx < DE_LENGTH_OF_ARRAY(callCounts); ++callCountNdx) 33553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry withoutBarrierGroup->addChild(new ConcurrentAtomicCounterCase(m_context, (std::string("atomic_counter_dispatch_") + de::toString(callCounts[callCountNdx]) + "_calls_" + counterInvocations[invocationNdx].name + "_invocations").c_str(), "", callCounts[callCountNdx], counterInvocations[invocationNdx].count)); 33563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 33573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int invocationNdx = 0; invocationNdx < DE_LENGTH_OF_ARRAY(counterInvocations); ++invocationNdx) 33583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int callCountNdx = 0; callCountNdx < DE_LENGTH_OF_ARRAY(callCounts); ++callCountNdx) 33593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry withoutBarrierGroup->addChild(new ConcurrentSSBOAtomicCounterMixedCase(m_context, (std::string("ssbo_atomic_counter_mixed_dispatch_") + de::toString(callCounts[callCountNdx]) + "_calls_" + counterInvocations[invocationNdx].name + "_invocations").c_str(), "", callCounts[callCountNdx], counterInvocations[invocationNdx].count)); 33603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 33613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 33623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 33633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 33643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 33653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // Functional 33663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // gles31 33673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // deqp 3368