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 Shader atomic operation tests. 223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "es31fShaderAtomicOpTests.hpp" 253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluShaderProgram.hpp" 263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluShaderUtil.hpp" 273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluRenderContext.hpp" 283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluObjectWrapper.hpp" 293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluProgramInterfaceQuery.hpp" 303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuVector.hpp" 313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuTestLog.hpp" 323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuVectorUtil.hpp" 333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuFormatUtil.hpp" 343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deStringUtil.hpp" 353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deRandom.hpp" 363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glwFunctions.hpp" 373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glwEnums.hpp" 383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <algorithm> 403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <set> 413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 423c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace deqp 433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 443c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace gles31 453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 463c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace Functional 473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 493c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::string; 503c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::vector; 513c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::TestLog; 523c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::UVec3; 533c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::set; 543c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing namespace glu; 553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 563c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<typename T, int Size> 573c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline T product (const tcu::Vector<T, Size>& v) 583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry T res = v[0]; 603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 1; ndx < Size; ndx++) 613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry res *= v[ndx]; 623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return res; 633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 653c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass ShaderAtomicOpCase : public TestCase 663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 673c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ShaderAtomicOpCase (Context& context, const char* name, const char* funcName, AtomicOperandType operandType, DataType type, Precision precision, const UVec3& workGroupSize); 693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ~ShaderAtomicOpCase (void); 703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void init (void); 723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void deinit (void); 733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IterateResult iterate (void); 743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 753c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry virtual void getInputs (int numValues, int stride, void* inputs) const = 0; 773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry virtual bool verify (int numValues, int inputStride, const void* inputs, int outputStride, const void* outputs, int groupStride, const void* groupOutputs) const = 0; 783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const string m_funcName; 803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const AtomicOperandType m_operandType; 813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const DataType m_type; 823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const Precision m_precision; 833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const UVec3 m_workGroupSize; 853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const UVec3 m_numWorkGroups; 863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deUint32 m_initialValue; 883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 893c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate: 903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ShaderAtomicOpCase (const ShaderAtomicOpCase& other); 913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ShaderAtomicOpCase& operator= (const ShaderAtomicOpCase& other); 923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ShaderProgram* m_program; 943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 963c827367444ee418f129b2c238299f49d3264554Jarkko PoyryShaderAtomicOpCase::ShaderAtomicOpCase (Context& context, const char* name, const char* funcName, AtomicOperandType operandType, DataType type, Precision precision, const UVec3& workGroupSize) 973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : TestCase (context, name, funcName) 983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_funcName (funcName) 993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_operandType (operandType) 1003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_type (type) 1013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_precision (precision) 1023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_workGroupSize (workGroupSize) 1033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_numWorkGroups (4,4,4) 1043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_initialValue (0) 1053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_program (DE_NULL) 1063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1093c827367444ee418f129b2c238299f49d3264554Jarkko PoyryShaderAtomicOpCase::~ShaderAtomicOpCase (void) 1103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ShaderAtomicOpCase::deinit(); 1123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1143c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ShaderAtomicOpCase::init (void) 1153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool isSSBO = m_operandType == ATOMIC_OPERAND_BUFFER_VARIABLE; 1173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const char* precName = getPrecisionName(m_precision); 1183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const char* typeName = getDataTypeName(m_type); 11975be7fae1949a801c080530de53bdf123abb517aPyry Haulos 12075be7fae1949a801c080530de53bdf123abb517aPyry Haulos const DataType outType = isSSBO ? m_type : glu::TYPE_UINT; 12175be7fae1949a801c080530de53bdf123abb517aPyry Haulos const char* outTypeName = getDataTypeName(outType); 12275be7fae1949a801c080530de53bdf123abb517aPyry Haulos 1233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const deUint32 numValues = product(m_workGroupSize)*product(m_numWorkGroups); 1243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::ostringstream src; 1253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry src << "#version 310 es\n" 1273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "layout(local_size_x = " << m_workGroupSize.x() 1283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << ", local_size_y = " << m_workGroupSize.y() 1293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << ", local_size_z = " << m_workGroupSize.z() << ") in;\n" 1303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "layout(binding = 0) buffer InOut\n" 1313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "{\n" 1323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " " << precName << " " << typeName << " inputValues[" << numValues << "];\n" 13375be7fae1949a801c080530de53bdf123abb517aPyry Haulos << " " << precName << " " << outTypeName << " outputValues[" << numValues << "];\n" 13475be7fae1949a801c080530de53bdf123abb517aPyry Haulos << " " << (isSSBO ? "coherent " : "") << precName << " " << outTypeName << " groupValues[" << product(m_numWorkGroups) << "];\n" 1353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "} sb_inout;\n"; 1363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!isSSBO) 1383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry src << "shared " << precName << " " << typeName << " s_var;\n"; 1393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry src << "\n" 1413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "void main (void)\n" 1423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "{\n" 1433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " uint localSize = gl_WorkGroupSize.x*gl_WorkGroupSize.y*gl_WorkGroupSize.z;\n" 1443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " uint globalNdx = gl_NumWorkGroups.x*gl_NumWorkGroups.y*gl_WorkGroupID.z + gl_NumWorkGroups.x*gl_WorkGroupID.y + gl_WorkGroupID.x;\n" 1453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " uint globalOffs = localSize*globalNdx;\n" 1463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " uint offset = globalOffs + gl_LocalInvocationIndex;\n" 1473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "\n"; 1483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (isSSBO) 1503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 15175be7fae1949a801c080530de53bdf123abb517aPyry Haulos DE_ASSERT(outType == m_type); 1523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry src << " sb_inout.outputValues[offset] = " << m_funcName << "(sb_inout.groupValues[globalNdx], sb_inout.inputValues[offset]);\n"; 1533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 1543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 1553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 15675be7fae1949a801c080530de53bdf123abb517aPyry Haulos const string castBeg = outType != m_type ? (string(outTypeName) + "(") : string(""); 15775be7fae1949a801c080530de53bdf123abb517aPyry Haulos const char* const castEnd = outType != m_type ? ")" : ""; 15875be7fae1949a801c080530de53bdf123abb517aPyry Haulos 1593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry src << " if (gl_LocalInvocationIndex == 0u)\n" 1603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " s_var = " << typeName << "(" << tcu::toHex(m_initialValue) << "u);\n" 1618852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry << " barrier();\n" 16275be7fae1949a801c080530de53bdf123abb517aPyry Haulos << " " << precName << " " << typeName << " res = " << m_funcName << "(s_var, sb_inout.inputValues[offset]);\n" 16375be7fae1949a801c080530de53bdf123abb517aPyry Haulos << " sb_inout.outputValues[offset] = " << castBeg << "res" << castEnd << ";\n" 1648852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry << " barrier();\n" 1653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " if (gl_LocalInvocationIndex == 0u)\n" 16675be7fae1949a801c080530de53bdf123abb517aPyry Haulos << " sb_inout.groupValues[globalNdx] = " << castBeg << "s_var" << castEnd << ";\n"; 1673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 1683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry src << "}\n"; 1703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(!m_program); 1723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_program = new ShaderProgram(m_context.getRenderContext(), ProgramSources() << ComputeSource(src.str())); 1733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << *m_program; 1753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!m_program->isOk()) 1773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry delete m_program; 1793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_program = DE_NULL; 1803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw tcu::TestError("Compile failed"); 1813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 1823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1843c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ShaderAtomicOpCase::deinit (void) 1853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry delete m_program; 1873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_program = DE_NULL; 1883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1903c827367444ee418f129b2c238299f49d3264554Jarkko PoyryShaderAtomicOpCase::IterateResult ShaderAtomicOpCase::iterate (void) 1913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const deUint32 program = m_program->getProgram(); 1943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const Buffer inoutBuffer (m_context.getRenderContext()); 1953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const deUint32 blockNdx = gl.getProgramResourceIndex(program, GL_SHADER_STORAGE_BLOCK, "InOut"); 1963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const InterfaceBlockInfo blockInfo = getProgramInterfaceBlockInfo(gl, program, GL_SHADER_STORAGE_BLOCK, blockNdx); 1973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const deUint32 inVarNdx = gl.getProgramResourceIndex(program, GL_BUFFER_VARIABLE, "InOut.inputValues[0]"); 1983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const InterfaceVariableInfo inVarInfo = getProgramInterfaceVariableInfo(gl, program, GL_BUFFER_VARIABLE, inVarNdx); 1993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const deUint32 outVarNdx = gl.getProgramResourceIndex(program, GL_BUFFER_VARIABLE, "InOut.outputValues[0]"); 2003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const InterfaceVariableInfo outVarInfo = getProgramInterfaceVariableInfo(gl, program, GL_BUFFER_VARIABLE, outVarNdx); 2013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const deUint32 groupVarNdx = gl.getProgramResourceIndex(program, GL_BUFFER_VARIABLE, "InOut.groupValues[0]"); 2023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const InterfaceVariableInfo groupVarInfo = getProgramInterfaceVariableInfo(gl, program, GL_BUFFER_VARIABLE, groupVarNdx); 2033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const deUint32 numValues = product(m_workGroupSize)*product(m_numWorkGroups); 2043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TCU_CHECK(inVarInfo.arraySize == numValues && 2063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry outVarInfo.arraySize == numValues && 2073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry groupVarInfo.arraySize == product(m_numWorkGroups)); 2083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.useProgram(program); 2103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Setup buffer. 2123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vector<deUint8> bufData(blockInfo.dataSize); 2143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::fill(bufData.begin(), bufData.end(), 0); 2153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry getInputs((int)numValues, (int)inVarInfo.arrayStride, &bufData[0] + inVarInfo.offset); 2173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_operandType == ATOMIC_OPERAND_BUFFER_VARIABLE) 2193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (deUint32 valNdx = 0; valNdx < product(m_numWorkGroups); valNdx++) 2213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *(deUint32*)(&bufData[0] + groupVarInfo.offset + groupVarInfo.arrayStride*valNdx) = m_initialValue; 2223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindBuffer(GL_SHADER_STORAGE_BUFFER, *inoutBuffer); 2253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bufferData(GL_SHADER_STORAGE_BUFFER, blockInfo.dataSize, &bufData[0], GL_STATIC_READ); 2263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, *inoutBuffer); 2273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "Output buffer setup failed"); 2283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.dispatchCompute(m_numWorkGroups.x(), m_numWorkGroups.y(), m_numWorkGroups.z()); 2313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Read back and compare 2333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const void* resPtr = gl.mapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, blockInfo.dataSize, GL_MAP_READ_BIT); 2353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool isOk = true; 2363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBufferRange()"); 2383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TCU_CHECK(resPtr); 2393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry isOk = verify((int)numValues, 2413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry (int)inVarInfo.arrayStride, (const deUint8*)resPtr + inVarInfo.offset, 2423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry (int)outVarInfo.arrayStride, (const deUint8*)resPtr + outVarInfo.offset, 2433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry (int)groupVarInfo.arrayStride, (const deUint8*)resPtr + groupVarInfo.offset); 2443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.unmapBuffer(GL_SHADER_STORAGE_BUFFER); 2463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer()"); 2473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL, 2493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry isOk ? "Pass" : "Comparison failed"); 2503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return STOP; 2533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 2543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2553c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass ShaderAtomicAddCase : public ShaderAtomicOpCase 2563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2573c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 2583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ShaderAtomicAddCase (Context& context, const char* name, AtomicOperandType operandType, DataType type, Precision precision) 2593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : ShaderAtomicOpCase(context, name, "atomicAdd", operandType, type, precision, UVec3(3,2,1)) 2603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_initialValue = 1; 2623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2643c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 2653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void getInputs (int numValues, int stride, void* inputs) const 2663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry de::Random rnd (deStringHash(getName())); 2683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int maxVal = m_precision == PRECISION_LOWP ? 2 : 32; 2693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int minVal = 1; 2703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // \todo [2013-09-04 pyry] Negative values! 2723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int valNdx = 0; valNdx < numValues; valNdx++) 2743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *(int*)((deUint8*)inputs + stride*valNdx) = rnd.getInt(minVal, maxVal); 2753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool verify (int numValues, int inputStride, const void* inputs, int outputStride, const void* outputs, int groupStride, const void* groupOutputs) const 2783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int workGroupSize = (int)product(m_workGroupSize); 2803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numWorkGroups = numValues/workGroupSize; 2813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int groupNdx = 0; groupNdx < numWorkGroups; groupNdx++) 2833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int groupOffset = groupNdx*workGroupSize; 2853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int groupOutput = *(const int*)((const deUint8*)groupOutputs + groupNdx*groupStride); 2863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry set<int> outValues; 2873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool maxFound = false; 2883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int valueSum = (int)m_initialValue; 2893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int localNdx = 0; localNdx < workGroupSize; localNdx++) 2913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int inputValue = *(const int*)((const deUint8*)inputs + inputStride*(groupOffset+localNdx)); 2933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry valueSum += inputValue; 2943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (groupOutput != valueSum) 2973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << TestLog::Message << "ERROR: at group " << groupNdx << ": expected sum " << valueSum << ", got " << groupOutput << TestLog::EndMessage; 2993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 3003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 3013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int localNdx = 0; localNdx < workGroupSize; localNdx++) 3033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 3043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int inputValue = *(const int*)((const deUint8*)inputs + inputStride*(groupOffset+localNdx)); 3053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int outputValue = *(const int*)((const deUint8*)outputs + outputStride*(groupOffset+localNdx)); 3063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!de::inRange(outputValue, (int)m_initialValue, valueSum-inputValue)) 3083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 3093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << TestLog::Message << "ERROR: at group " << groupNdx << ", invocation " << localNdx 3103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << ": expected value in range [" << m_initialValue << ", " << (valueSum-inputValue) 3113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "], got " << outputValue 3123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << TestLog::EndMessage; 3133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 3143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 3153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (outValues.find(outputValue) != outValues.end()) 3173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 3183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << TestLog::Message << "ERROR: at group " << groupNdx << ", invocation " << localNdx 3193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << ": found duplicate value " << outputValue 3203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << TestLog::EndMessage; 3213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 3223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 3233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry outValues.insert(outputValue); 3253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (outputValue == valueSum-inputValue) 3263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry maxFound = true; 3273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 3283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!maxFound) 3303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 3313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << TestLog::Message << "ERROR: could not find maximum expected value from group " << groupNdx << TestLog::EndMessage; 3323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 3333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 3343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (outValues.find((int)m_initialValue) == outValues.end()) 3363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 3373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << TestLog::Message << "ERROR: could not find initial value from group " << groupNdx << TestLog::EndMessage; 3383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 3393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 3403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 3413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return true; 3433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 3443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 3453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 346664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyry 347664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyrystatic int getPrecisionNumIntegerBits (glu::Precision precision) 348664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyry{ 349664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyry switch (precision) 350664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyry { 351664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyry case glu::PRECISION_HIGHP: return 32; 352664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyry case glu::PRECISION_MEDIUMP: return 16; 353664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyry case glu::PRECISION_LOWP: return 9; 354664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyry default: 355664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyry DE_ASSERT(false); 356664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyry return 0; 357664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyry } 358664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyry} 359664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyry 360664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyrystatic deUint32 getPrecisionMask (int numPreciseBits) 361664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyry{ 362664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyry // \note: bit shift with larger or equal than var length is undefined, use 64 bit ints 363664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyry return (deUint32)((((deUint64)1u) << numPreciseBits) - 1) ; 364664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyry} 365664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyry 366664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyrystatic bool intEqualsAfterUintCast (deInt32 value, deUint32 casted, glu::Precision precision) 367664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyry{ 368664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyry // Bit format of 'casted' = [ uint -> highp uint promotion bits (0) ] [ sign extend bits (s) ] [ value bits ] 369664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyry // |--min len---| 370664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyry // |---------------signed length---------| 371664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyry // |-------------------------------- highp uint length ----------------------------| 372664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyry 373664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyry const deUint32 reference = (deUint32)value; 374664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyry const int signBitOn = value < 0; 375664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyry const int numPreciseBits = getPrecisionNumIntegerBits(precision); 376664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyry const deUint32 preciseMask = getPrecisionMask(numPreciseBits); 377664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyry 378664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyry // Lowest N bits must match, N = minimum precision 379664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyry if ((reference & preciseMask) != (casted & preciseMask)) 380664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyry return false; 381664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyry 382664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyry // Other lowest bits must match the sign and the remaining (topmost) if any must be 0 383664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyry for (int signedIntegerLength = numPreciseBits; signedIntegerLength <= 32; ++signedIntegerLength) 384664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyry { 385664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyry const deUint32 signBits = (signBitOn) ? (getPrecisionMask(signedIntegerLength)) : (0u); 386664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyry 387664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyry if ((signBits & ~preciseMask) == (casted & ~preciseMask)) 388664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyry return true; 389664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyry } 390664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyry return false; 391664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyry} 392664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyry 393664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyrystatic bool containsAfterUintCast (const std::set<deInt32>& haystack, deUint32 needle, glu::Precision precision) 394664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyry{ 395664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyry for (std::set<deInt32>::const_iterator it = haystack.begin(); it != haystack.end(); ++it) 396664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyry if (intEqualsAfterUintCast(*it, needle, precision)) 397664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyry return true; 398664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyry return false; 399664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyry} 400664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyry 401664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyrystatic bool containsAfterUintCast (const std::set<deUint32>& haystack, deInt32 needle, glu::Precision precision) 402664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyry{ 403664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyry for (std::set<deUint32>::const_iterator it = haystack.begin(); it != haystack.end(); ++it) 404664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyry if (intEqualsAfterUintCast(needle, *it, precision)) 405664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyry return true; 406664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyry return false; 407664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyry} 408664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyry 4093c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass ShaderAtomicMinCase : public ShaderAtomicOpCase 4103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 4113c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 4123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ShaderAtomicMinCase (Context& context, const char* name, AtomicOperandType operandType, DataType type, Precision precision) 4133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : ShaderAtomicOpCase(context, name, "atomicMin", operandType, type, precision, UVec3(3,2,1)) 4143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 4153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_initialValue = m_precision == PRECISION_LOWP ? 100 : 1000; 4163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 4173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4183c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 4193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void getInputs (int numValues, int stride, void* inputs) const 4203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 4213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry de::Random rnd (deStringHash(getName())); 4223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool isSigned = m_type == TYPE_INT; 4233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int maxVal = m_precision == PRECISION_LOWP ? 100 : 1000; 4243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int minVal = isSigned ? -maxVal : 0; 4253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int valNdx = 0; valNdx < numValues; valNdx++) 4273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *(int*)((deUint8*)inputs + stride*valNdx) = rnd.getInt(minVal, maxVal); 4283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 4293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool verify (int numValues, int inputStride, const void* inputs, int outputStride, const void* outputs, int groupStride, const void* groupOutputs) const 4313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 4323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int workGroupSize = (int)product(m_workGroupSize); 4333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numWorkGroups = numValues/workGroupSize; 434664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyry bool anyError = false; 4353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int groupNdx = 0; groupNdx < numWorkGroups; groupNdx++) 4373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 438664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyry const int groupOffset = groupNdx*workGroupSize; 439664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyry const deUint32 groupOutput = *(const deUint32*)((const deUint8*)groupOutputs + groupNdx*groupStride); 440664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyry set<deInt32> inValues; 441664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyry set<deUint32> outValues; 442664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyry int minValue = (int)m_initialValue; 4433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int localNdx = 0; localNdx < workGroupSize; localNdx++) 4453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 446664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyry const deInt32 inputValue = *(const deInt32*)((const deUint8*)inputs + inputStride*(groupOffset+localNdx)); 4473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry inValues.insert(inputValue); 4483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry minValue = de::min(inputValue, minValue); 4493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 4503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 451664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyry if (!intEqualsAfterUintCast(minValue, groupOutput, m_precision)) 4523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 453664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyry m_testCtx.getLog() 454664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyry << TestLog::Message 455664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyry << "ERROR: at group " << groupNdx 456664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyry << ": expected minimum " << minValue << " (" << tcu::Format::Hex<8>((deUint32)minValue) << ")" 457664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyry << ", got " << groupOutput << " (" << tcu::Format::Hex<8>(groupOutput) << ")" 458664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyry << TestLog::EndMessage; 459664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyry anyError = true; 4603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 4613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int localNdx = 0; localNdx < workGroupSize; localNdx++) 4633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 464664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyry const deUint32 outputValue = *(const deUint32*)((const deUint8*)outputs + outputStride*(groupOffset+localNdx)); 4653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 466664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyry if (!containsAfterUintCast(inValues, outputValue, m_precision) && 467664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyry !intEqualsAfterUintCast((deInt32)m_initialValue, outputValue, m_precision)) 4683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 4693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << TestLog::Message << "ERROR: at group " << groupNdx << ", invocation " << localNdx 4703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << ": found unexpected value " << outputValue 471664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyry << " (" << tcu::Format::Hex<8>(outputValue) << ")" 4723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << TestLog::EndMessage; 473664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyry anyError = true; 4743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 4753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry outValues.insert(outputValue); 4773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 4783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 479664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyry if (!containsAfterUintCast(outValues, (int)m_initialValue, m_precision)) 4803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 4813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << TestLog::Message << "ERROR: could not find initial value from group " << groupNdx << TestLog::EndMessage; 482664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyry anyError = true; 4833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 4843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 4853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 486664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyry return !anyError; 4873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 4883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 4893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4903c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass ShaderAtomicMaxCase : public ShaderAtomicOpCase 4913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 4923c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 4933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ShaderAtomicMaxCase (Context& context, const char* name, AtomicOperandType operandType, DataType type, Precision precision) 4943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : ShaderAtomicOpCase(context, name, "atomicMax", operandType, type, precision, UVec3(3,2,1)) 4953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 4963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool isSigned = m_type == TYPE_INT; 4973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_initialValue = isSigned ? (m_precision == PRECISION_LOWP ? -100 : -1000) : 0; 4983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 4993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5003c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 5013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void getInputs (int numValues, int stride, void* inputs) const 5023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 5033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry de::Random rnd (deStringHash(getName())); 5043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool isSigned = m_type == TYPE_INT; 5053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int maxVal = m_precision == PRECISION_LOWP ? 100 : 1000; 5063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int minVal = isSigned ? -maxVal : 0; 5073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int valNdx = 0; valNdx < numValues; valNdx++) 5093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *(int*)((deUint8*)inputs + stride*valNdx) = rnd.getInt(minVal, maxVal); 5103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 5113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool verify (int numValues, int inputStride, const void* inputs, int outputStride, const void* outputs, int groupStride, const void* groupOutputs) const 5133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 5143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int workGroupSize = (int)product(m_workGroupSize); 5153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numWorkGroups = numValues/workGroupSize; 516664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyry bool anyError = false; 5173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int groupNdx = 0; groupNdx < numWorkGroups; groupNdx++) 5193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 520664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyry const int groupOffset = groupNdx*workGroupSize; 521664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyry const deUint32 groupOutput = *(const deUint32*)((const deUint8*)groupOutputs + groupNdx*groupStride); 522664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyry set<int> inValues; 523664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyry set<deUint32> outValues; 524664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyry int maxValue = (int)m_initialValue; 5253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int localNdx = 0; localNdx < workGroupSize; localNdx++) 5273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 528664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyry const deInt32 inputValue = *(const deInt32*)((const deUint8*)inputs + inputStride*(groupOffset+localNdx)); 5293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry inValues.insert(inputValue); 5303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry maxValue = de::max(maxValue, inputValue); 5313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 5323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 533664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyry if (!intEqualsAfterUintCast(maxValue, groupOutput, m_precision)) 5343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 535664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyry m_testCtx.getLog() 536664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyry << TestLog::Message 537664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyry << "ERROR: at group " << groupNdx 538664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyry << ": expected maximum " << maxValue << " (" << tcu::Format::Hex<8>((deUint32)maxValue) << ")" 539664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyry << ", got " << groupOutput << " (" << tcu::Format::Hex<8>(groupOutput) << ")" 540664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyry << TestLog::EndMessage; 541664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyry anyError = true; 5423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 5433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int localNdx = 0; localNdx < workGroupSize; localNdx++) 5453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 546664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyry const deUint32 outputValue = *(const deUint32*)((const deUint8*)outputs + outputStride*(groupOffset+localNdx)); 5473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 548664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyry if (!containsAfterUintCast(inValues, outputValue, m_precision) && 549664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyry !intEqualsAfterUintCast((deInt32)m_initialValue, outputValue, m_precision)) 5503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 5513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << TestLog::Message << "ERROR: at group " << groupNdx << ", invocation " << localNdx 5523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << ": found unexpected value " << outputValue 553664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyry << " (" << tcu::Format::Hex<8>(outputValue) << ")" 5543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << TestLog::EndMessage; 555664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyry anyError = true; 5563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 5573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry outValues.insert(outputValue); 5593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 5603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 561664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyry if (!containsAfterUintCast(outValues, (int)m_initialValue, m_precision)) 5623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 5633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << TestLog::Message << "ERROR: could not find initial value from group " << groupNdx << TestLog::EndMessage; 564664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyry anyError = true; 5653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 5663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 5673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 568664e0500b4d1458fae75baf99cc4368442a0f370Jarkko Pöyry return !anyError; 5693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 5703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 5713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5723c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass ShaderAtomicAndCase : public ShaderAtomicOpCase 5733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 5743c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 5753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ShaderAtomicAndCase (Context& context, const char* name, AtomicOperandType operandType, DataType type, Precision precision) 5763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : ShaderAtomicOpCase(context, name, "atomicAnd", operandType, type, precision, UVec3(3,2,1)) 5773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 5783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numBits = m_precision == PRECISION_HIGHP ? 32 : 5793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_precision == PRECISION_MEDIUMP ? 16 : 8; 5803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const deUint32 valueMask = numBits == 32 ? ~0u : (1u<<numBits)-1u; 5813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_initialValue = ~((1u<<(numBits-1u)) | 1u) & valueMask; // All bits except lowest and highest set. 5823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 5833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5843c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 5853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void getInputs (int numValues, int stride, void* inputs) const 5863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 5873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry de::Random rnd (deStringHash(getName())); 5883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int workGroupSize = (int)product(m_workGroupSize); 5893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numWorkGroups = numValues/workGroupSize; 5903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numBits = m_precision == PRECISION_HIGHP ? 32 : 5913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_precision == PRECISION_MEDIUMP ? 16 : 8; 5923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const deUint32 valueMask = numBits == 32 ? ~0u : (1u<<numBits)-1u; 5933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int groupNdx = 0; groupNdx < numWorkGroups; groupNdx++) 5953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 5963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int groupOffset = groupNdx*workGroupSize; 5973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const deUint32 groupMask = 1<<rnd.getInt(0, numBits-2); // One bit is always set. 5983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int localNdx = 0; localNdx < workGroupSize; localNdx++) 6003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *(deUint32*)((deUint8*)inputs + stride*(groupOffset+localNdx)) = (rnd.getUint32() & valueMask) | groupMask; 6013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 6023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 6033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool verify (int numValues, int inputStride, const void* inputs, int outputStride, const void* outputs, int groupStride, const void* groupOutputs) const 6053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 6063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int workGroupSize = (int)product(m_workGroupSize); 6073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numWorkGroups = numValues/workGroupSize; 6083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int groupNdx = 0; groupNdx < numWorkGroups; groupNdx++) 6103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 6113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int groupOffset = groupNdx*workGroupSize; 6123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const deUint32 groupOutput = *(const deUint32*)((const deUint8*)groupOutputs + groupNdx*groupStride); 6133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deUint32 expectedValue = m_initialValue; 6143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int localNdx = 0; localNdx < workGroupSize; localNdx++) 6163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 6173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const deUint32 inputValue = *(const deUint32*)((const deUint8*)inputs + inputStride*(groupOffset+localNdx)); 6183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry expectedValue &= inputValue; 6193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 6203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (expectedValue != groupOutput) 6223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 6233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << TestLog::Message << "ERROR: at group " << groupNdx << ": expected " << tcu::toHex(expectedValue) << ", got " << tcu::toHex(groupOutput) << TestLog::EndMessage; 6243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 6253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 6263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int localNdx = 0; localNdx < workGroupSize; localNdx++) 6283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 6293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const deUint32 outputValue = *(const deUint32*)((const deUint8*)outputs + outputStride*(groupOffset+localNdx)); 6303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if ((outputValue & ~m_initialValue) != 0) 6323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 6333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << TestLog::Message << "ERROR: at group " << groupNdx << ", invocation " << localNdx 6343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << ": found unexpected value " << tcu::toHex(outputValue) 6353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << TestLog::EndMessage; 6363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 6373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 6383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 6393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 6403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return true; 6423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 6433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 6443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6453c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass ShaderAtomicOrCase : public ShaderAtomicOpCase 6463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 6473c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 6483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ShaderAtomicOrCase (Context& context, const char* name, AtomicOperandType operandType, DataType type, Precision precision) 6493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : ShaderAtomicOpCase(context, name, "atomicOr", operandType, type, precision, UVec3(3,2,1)) 6503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 6513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_initialValue = 1u; // Lowest bit set. 6523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 6533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6543c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 6553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void getInputs (int numValues, int stride, void* inputs) const 6563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 6573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry de::Random rnd (deStringHash(getName())); 6583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int workGroupSize = (int)product(m_workGroupSize); 6593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numWorkGroups = numValues/workGroupSize; 6603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numBits = m_precision == PRECISION_HIGHP ? 32 : 6613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_precision == PRECISION_MEDIUMP ? 16 : 8; 6623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int groupNdx = 0; groupNdx < numWorkGroups; groupNdx++) 6643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 6653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int groupOffset = groupNdx*workGroupSize; 6663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int localNdx = 0; localNdx < workGroupSize; localNdx++) 6683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *(deUint32*)((deUint8*)inputs + stride*(groupOffset+localNdx)) = 1u<<rnd.getInt(0, numBits-1); 6693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 6703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 6713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool verify (int numValues, int inputStride, const void* inputs, int outputStride, const void* outputs, int groupStride, const void* groupOutputs) const 6733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 6743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int workGroupSize = (int)product(m_workGroupSize); 6753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numWorkGroups = numValues/workGroupSize; 6763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int groupNdx = 0; groupNdx < numWorkGroups; groupNdx++) 6783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 6793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int groupOffset = groupNdx*workGroupSize; 6803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const deUint32 groupOutput = *(const deUint32*)((const deUint8*)groupOutputs + groupNdx*groupStride); 6813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deUint32 expectedValue = m_initialValue; 6823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int localNdx = 0; localNdx < workGroupSize; localNdx++) 6843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 6853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const deUint32 inputValue = *(const deUint32*)((const deUint8*)inputs + inputStride*(groupOffset+localNdx)); 6863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry expectedValue |= inputValue; 6873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 6883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (expectedValue != groupOutput) 6903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 6913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << TestLog::Message << "ERROR: at group " << groupNdx << ": expected " << tcu::toHex(expectedValue) << ", got " << tcu::toHex(groupOutput) << TestLog::EndMessage; 6923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 6933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 6943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int localNdx = 0; localNdx < workGroupSize; localNdx++) 6963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 6973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const deUint32 outputValue = *(const deUint32*)((const deUint8*)outputs + outputStride*(groupOffset+localNdx)); 6983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if ((outputValue & m_initialValue) == 0) 7003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 7013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << TestLog::Message << "ERROR: at group " << groupNdx << ", invocation " << localNdx 7023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << ": found unexpected value " << tcu::toHex(outputValue) 7033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << TestLog::EndMessage; 7043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 7053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 7063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 7073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 7083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return true; 7103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 7113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 7123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7133c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass ShaderAtomicXorCase : public ShaderAtomicOpCase 7143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 7153c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 7163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ShaderAtomicXorCase (Context& context, const char* name, AtomicOperandType operandType, DataType type, Precision precision) 7173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : ShaderAtomicOpCase(context, name, "atomicXor", operandType, type, precision, UVec3(3,2,1)) 7183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 7193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_initialValue = 0; 7203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 7213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7223c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 7233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void getInputs (int numValues, int stride, void* inputs) const 7243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 7253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry de::Random rnd (deStringHash(getName())); 7263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int workGroupSize = (int)product(m_workGroupSize); 7273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numWorkGroups = numValues/workGroupSize; 7283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int groupNdx = 0; groupNdx < numWorkGroups; groupNdx++) 7303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 7313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int groupOffset = groupNdx*workGroupSize; 7323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // First uses random bit-pattern. 7343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *(deUint32*)((deUint8*)inputs + stride*(groupOffset)) = rnd.getUint32(); 7353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Rest have either all or no bits set. 7373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int localNdx = 1; localNdx < workGroupSize; localNdx++) 7383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *(deUint32*)((deUint8*)inputs + stride*(groupOffset+localNdx)) = rnd.getBool() ? ~0u : 0u; 7393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 7403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 7413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool verify (int numValues, int inputStride, const void* inputs, int outputStride, const void* outputs, int groupStride, const void* groupOutputs) const 7433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 7443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int workGroupSize = (int)product(m_workGroupSize); 7453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numWorkGroups = numValues/workGroupSize; 7463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numBits = m_precision == PRECISION_HIGHP ? 32 : 7473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_precision == PRECISION_MEDIUMP ? 16 : 8; 7483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const deUint32 compareMask = numBits == 32 ? ~0u : (1u<<numBits)-1u; 7493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int groupNdx = 0; groupNdx < numWorkGroups; groupNdx++) 7513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 7523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int groupOffset = groupNdx*workGroupSize; 7533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const deUint32 groupOutput = *(const deUint32*)((const deUint8*)groupOutputs + groupNdx*groupStride); 7543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const deUint32 randomValue = *(const int*)((const deUint8*)inputs + inputStride*groupOffset); 7553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const deUint32 expected0 = randomValue ^ 0u; 7563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const deUint32 expected1 = randomValue ^ ~0u; 7573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int numXorZeros = (m_initialValue == 0) ? 1 : 0; 7583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int localNdx = 1; localNdx < workGroupSize; localNdx++) 7603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 7613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const deUint32 inputValue = *(const deUint32*)((const deUint8*)inputs + inputStride*(groupOffset+localNdx)); 7623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (inputValue == 0) 7633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry numXorZeros += 1; 7643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 7653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const deUint32 expected = (numXorZeros%2 == 0) ? expected0 : expected1; 7673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if ((groupOutput & compareMask) != (expected & compareMask)) 7693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 7703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << TestLog::Message << "ERROR: at group " << groupNdx << ": expected " << tcu::toHex(expected0) 7713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " or " << tcu::toHex(expected1) << " (compare mask " << tcu::toHex(compareMask) 7723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "), got " << tcu::toHex(groupOutput) << TestLog::EndMessage; 7733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 7743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 7753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int localNdx = 0; localNdx < workGroupSize; localNdx++) 7773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 7783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const deUint32 outputValue = *(const deUint32*)((const deUint8*)outputs + outputStride*(groupOffset+localNdx)); 7793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if ((outputValue&compareMask) != 0 && 7813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry (outputValue&compareMask) != compareMask && 7823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry (outputValue&compareMask) != (expected0&compareMask) && 7833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry (outputValue&compareMask) != (expected1&compareMask)) 7843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 7853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << TestLog::Message << "ERROR: at group " << groupNdx << ", invocation " << localNdx 7863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << ": found unexpected value " << tcu::toHex(outputValue) 7873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << TestLog::EndMessage; 7883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 7893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 7903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 7913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 7923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return true; 7943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 7953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 7963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7973c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass ShaderAtomicExchangeCase : public ShaderAtomicOpCase 7983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 7993c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 8003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ShaderAtomicExchangeCase (Context& context, const char* name, AtomicOperandType operandType, DataType type, Precision precision) 8013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : ShaderAtomicOpCase(context, name, "atomicExchange", operandType, type, precision, UVec3(3,2,1)) 8023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 8033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_initialValue = 0; 8043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 8053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8063c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 8073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void getInputs (int numValues, int stride, void* inputs) const 8083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 8093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int workGroupSize = (int)product(m_workGroupSize); 8103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numWorkGroups = numValues/workGroupSize; 8113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int groupNdx = 0; groupNdx < numWorkGroups; groupNdx++) 8133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 8143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int groupOffset = groupNdx*workGroupSize; 8153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int localNdx = 0; localNdx < workGroupSize; localNdx++) 8173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *(int*)((deUint8*)inputs + stride*(groupOffset+localNdx)) = localNdx+1; 8183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 8193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 8203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool verify (int numValues, int inputStride, const void* inputs, int outputStride, const void* outputs, int groupStride, const void* groupOutputs) const 8223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 8233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int workGroupSize = (int)product(m_workGroupSize); 8243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numWorkGroups = numValues/workGroupSize; 8253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_UNREF(inputStride && inputs); 8273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int groupNdx = 0; groupNdx < numWorkGroups; groupNdx++) 8293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 8303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int groupOffset = groupNdx*workGroupSize; 8313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int groupOutput = *(const int*)((const deUint8*)groupOutputs + groupNdx*groupStride); 8323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry set<int> usedValues; 8333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int localNdx = 0; localNdx < workGroupSize; localNdx++) 8353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 8363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int outputValue = *(const int*)((const deUint8*)outputs + outputStride*(groupOffset+localNdx)); 8373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!de::inRange(outputValue, 0, workGroupSize) || usedValues.find(outputValue) != usedValues.end()) 8393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 8403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << TestLog::Message << "ERROR: at group " << groupNdx << ", invocation " << localNdx 8413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << ": found unexpected value " << outputValue 8423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << TestLog::EndMessage; 8433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 8443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 8453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry usedValues.insert(outputValue); 8463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 8473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!de::inRange(groupOutput, 0, workGroupSize) || usedValues.find(groupOutput) != usedValues.end()) 8493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 8503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << TestLog::Message << "ERROR: at group " << groupNdx << ": unexpected final value" << groupOutput << TestLog::EndMessage; 8513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 8523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 8533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 8543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return true; 8563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 8573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 8583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8593c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass ShaderAtomicCompSwapCase : public TestCase 8603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 8613c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 8623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ShaderAtomicCompSwapCase (Context& context, const char* name, AtomicOperandType operandType, DataType type, Precision precision); 8633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ~ShaderAtomicCompSwapCase (void); 8643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void init (void); 8663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void deinit (void); 8673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IterateResult iterate (void); 8683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8693c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 8703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8713c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate: 8723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ShaderAtomicCompSwapCase (const ShaderAtomicCompSwapCase& other); 8733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ShaderAtomicCompSwapCase& operator= (const ShaderAtomicCompSwapCase& other); 8743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const AtomicOperandType m_operandType; 8763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const DataType m_type; 8773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const Precision m_precision; 8783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const UVec3 m_workGroupSize; 8803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const UVec3 m_numWorkGroups; 8813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ShaderProgram* m_program; 8833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 8843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8853c827367444ee418f129b2c238299f49d3264554Jarkko PoyryShaderAtomicCompSwapCase::ShaderAtomicCompSwapCase (Context& context, const char* name, AtomicOperandType operandType, DataType type, Precision precision) 8863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : TestCase (context, name, "atomicCompSwap() Test") 8873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_operandType (operandType) 8883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_type (type) 8893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_precision (precision) 8903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_workGroupSize (3,2,1) 8913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_numWorkGroups (4,4,4) 8923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_program (DE_NULL) 8933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 8943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 8953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8963c827367444ee418f129b2c238299f49d3264554Jarkko PoyryShaderAtomicCompSwapCase::~ShaderAtomicCompSwapCase (void) 8973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 8983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ShaderAtomicCompSwapCase::deinit(); 8993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 9003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9013c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ShaderAtomicCompSwapCase::init (void) 9023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 9033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool isSSBO = m_operandType == ATOMIC_OPERAND_BUFFER_VARIABLE; 9043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const char* precName = getPrecisionName(m_precision); 9053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const char* typeName = getDataTypeName(m_type); 9063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const deUint32 numValues = product(m_workGroupSize)*product(m_numWorkGroups); 9073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::ostringstream src; 9083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry src << "#version 310 es\n" 9103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "layout(local_size_x = " << m_workGroupSize.x() 9113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << ", local_size_y = " << m_workGroupSize.y() 9123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << ", local_size_z = " << m_workGroupSize.z() << ") in;\n" 9133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "layout(binding = 0) buffer InOut\n" 9143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "{\n" 9153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " " << precName << " " << typeName << " compareValues[" << numValues << "];\n" 9163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " " << precName << " " << typeName << " exchangeValues[" << numValues << "];\n" 9173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " " << precName << " " << typeName << " outputValues[" << numValues << "];\n" 9183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " " << (isSSBO ? "coherent " : "") << precName << " " << typeName << " groupValues[" << product(m_numWorkGroups) << "];\n" 9193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "} sb_inout;\n"; 9203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!isSSBO) 9223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry src << "shared " << precName << " " << typeName << " s_var;\n"; 9233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry src << "\n" 9253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "void main (void)\n" 9263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "{\n" 9273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " uint localSize = gl_WorkGroupSize.x*gl_WorkGroupSize.y*gl_WorkGroupSize.z;\n" 9283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " uint globalNdx = gl_NumWorkGroups.x*gl_NumWorkGroups.y*gl_WorkGroupID.z + gl_NumWorkGroups.x*gl_WorkGroupID.y + gl_WorkGroupID.x;\n" 9293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " uint globalOffs = localSize*globalNdx;\n" 9303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " uint offset = globalOffs + gl_LocalInvocationIndex;\n" 9313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "\n"; 9323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!isSSBO) 9343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 9353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry src << " if (gl_LocalInvocationIndex == 0u)\n" 9363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " s_var = " << typeName << "(" << 0 << ");\n" 9373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "\n"; 9383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 9393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry src << " " << precName << " " << typeName << " compare = sb_inout.compareValues[offset];\n" 9413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " " << precName << " " << typeName << " exchange = sb_inout.exchangeValues[offset];\n" 9423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " " << precName << " " << typeName << " result;\n" 9438852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry << " bool swapDone = false;\n" 9443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "\n" 9453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " for (uint ndx = 0u; ndx < localSize; ndx++)\n" 9463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " {\n" 9478852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry << " barrier();\n" 9488852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry << " if (!swapDone)\n" 9498852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry << " {\n" 9508852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry << " result = atomicCompSwap(" << (isSSBO ? "sb_inout.groupValues[globalNdx]" : "s_var") << ", compare, exchange);\n" 9518852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry << " if (result == compare)\n" 9528852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry << " swapDone = true;\n" 9538852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry << " }\n" 9543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " }\n" 9553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "\n" 9563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " sb_inout.outputValues[offset] = result;\n"; 9573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!isSSBO) 9593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 9608852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry src << " barrier();\n" 9613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " if (gl_LocalInvocationIndex == 0u)\n" 9623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " sb_inout.groupValues[globalNdx] = s_var;\n"; 9633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 9643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry src << "}\n"; 9663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(!m_program); 9683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_program = new ShaderProgram(m_context.getRenderContext(), ProgramSources() << ComputeSource(src.str())); 9693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << *m_program; 9713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!m_program->isOk()) 9733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 9743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry delete m_program; 9753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_program = DE_NULL; 9763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw tcu::TestError("Compile failed"); 9773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 9783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 9793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9803c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ShaderAtomicCompSwapCase::deinit (void) 9813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 9823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry delete m_program; 9833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_program = DE_NULL; 9843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 9853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9863c827367444ee418f129b2c238299f49d3264554Jarkko PoyryShaderAtomicOpCase::IterateResult ShaderAtomicCompSwapCase::iterate (void) 9873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 9883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 9893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const deUint32 program = m_program->getProgram(); 9903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const Buffer inoutBuffer (m_context.getRenderContext()); 9913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const deUint32 blockNdx = gl.getProgramResourceIndex(program, GL_SHADER_STORAGE_BLOCK, "InOut"); 9923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const InterfaceBlockInfo blockInfo = getProgramInterfaceBlockInfo(gl, program, GL_SHADER_STORAGE_BLOCK, blockNdx); 9933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const deUint32 cmpVarNdx = gl.getProgramResourceIndex(program, GL_BUFFER_VARIABLE, "InOut.compareValues[0]"); 9943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const InterfaceVariableInfo cmpVarInfo = getProgramInterfaceVariableInfo(gl, program, GL_BUFFER_VARIABLE, cmpVarNdx); 9953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const deUint32 exhVarNdx = gl.getProgramResourceIndex(program, GL_BUFFER_VARIABLE, "InOut.exchangeValues[0]"); 9963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const InterfaceVariableInfo exhVarInfo = getProgramInterfaceVariableInfo(gl, program, GL_BUFFER_VARIABLE, exhVarNdx); 9973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const deUint32 outVarNdx = gl.getProgramResourceIndex(program, GL_BUFFER_VARIABLE, "InOut.outputValues[0]"); 9983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const InterfaceVariableInfo outVarInfo = getProgramInterfaceVariableInfo(gl, program, GL_BUFFER_VARIABLE, outVarNdx); 9993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const deUint32 groupVarNdx = gl.getProgramResourceIndex(program, GL_BUFFER_VARIABLE, "InOut.groupValues[0]"); 10003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const InterfaceVariableInfo groupVarInfo = getProgramInterfaceVariableInfo(gl, program, GL_BUFFER_VARIABLE, groupVarNdx); 10013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const deUint32 numValues = product(m_workGroupSize)*product(m_numWorkGroups); 10023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TCU_CHECK(cmpVarInfo.arraySize == numValues && 10043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry exhVarInfo.arraySize == numValues && 10053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry outVarInfo.arraySize == numValues && 10063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry groupVarInfo.arraySize == product(m_numWorkGroups)); 10073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.useProgram(program); 10093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // \todo [2013-09-05 pyry] Use randomized input values! 10113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Setup buffer. 10133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 10143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const deUint32 workGroupSize = product(m_workGroupSize); 10153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vector<deUint8> bufData (blockInfo.dataSize); 10163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::fill(bufData.begin(), bufData.end(), 0); 10183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (deUint32 ndx = 0; ndx < numValues; ndx++) 10203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *(deUint32*)(&bufData[0] + cmpVarInfo.offset + cmpVarInfo.arrayStride*ndx) = ndx%workGroupSize; 10213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (deUint32 ndx = 0; ndx < numValues; ndx++) 10233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *(deUint32*)(&bufData[0] + exhVarInfo.offset + exhVarInfo.arrayStride*ndx) = (ndx%workGroupSize)+1; 10243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindBuffer(GL_SHADER_STORAGE_BUFFER, *inoutBuffer); 10263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bufferData(GL_SHADER_STORAGE_BUFFER, blockInfo.dataSize, &bufData[0], GL_STATIC_READ); 10273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, *inoutBuffer); 10283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "Output buffer setup failed"); 10293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 10303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.dispatchCompute(m_numWorkGroups.x(), m_numWorkGroups.y(), m_numWorkGroups.z()); 10323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Read back and compare 10343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 10353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const void* resPtr = gl.mapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, blockInfo.dataSize, GL_MAP_READ_BIT); 10363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numWorkGroups = (int)product(m_numWorkGroups); 10373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int workGroupSize = (int)product(m_workGroupSize); 10383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool isOk = true; 10393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBufferRange()"); 10413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TCU_CHECK(resPtr); 10423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int groupNdx = 0; groupNdx < numWorkGroups; groupNdx++) 10443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 10453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int groupOffset = groupNdx*workGroupSize; 10463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int groupOutput = *(const int*)((const deUint8*)resPtr + groupVarInfo.offset + groupNdx*groupVarInfo.arrayStride); 10473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int localNdx = 0; localNdx < workGroupSize; localNdx++) 10493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 10503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int refValue = localNdx; 10513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int outputValue = *(const int*)((const deUint8*)resPtr + outVarInfo.offset + outVarInfo.arrayStride*(groupOffset+localNdx)); 10523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (outputValue != refValue) 10543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 10553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << TestLog::Message << "ERROR: at group " << groupNdx << ", invocation " << localNdx 10563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << ": expected " << refValue << ", got " << outputValue 10573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << TestLog::EndMessage; 10583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry isOk = false; 10593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry break; 10603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 10613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 10623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (groupOutput != workGroupSize) 10643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 10653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << TestLog::Message << "ERROR: at group " << groupNdx << ": expected" << workGroupSize << ", got " << groupOutput << TestLog::EndMessage; 10663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry isOk = false; 10673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry break; 10683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 10693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 10703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.unmapBuffer(GL_SHADER_STORAGE_BUFFER); 10723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer()"); 10733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL, 10753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry isOk ? "Pass" : "Comparison failed"); 10763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 10773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return STOP; 10793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 10803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10813c827367444ee418f129b2c238299f49d3264554Jarkko PoyryShaderAtomicOpTests::ShaderAtomicOpTests (Context& context, const char* name, AtomicOperandType operandType) 10823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : TestCaseGroup (context, name, "Atomic Operation Tests") 10833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_operandType (operandType) 10843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 10853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 10863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10873c827367444ee418f129b2c238299f49d3264554Jarkko PoyryShaderAtomicOpTests::~ShaderAtomicOpTests (void) 10883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 10893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 10903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10913c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<typename T> 10923c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic tcu::TestCaseGroup* createAtomicOpGroup (Context& context, AtomicOperandType operandType, const char* groupName) 10933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 10943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcu::TestCaseGroup *const group = new tcu::TestCaseGroup(context.getTestContext(), groupName, (string("Atomic ") + groupName).c_str()); 10953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry try 10963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 10973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int precNdx = 0; precNdx < PRECISION_LAST; precNdx++) 10983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 10993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int typeNdx = 0; typeNdx < 2; typeNdx++) 11003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 11013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const Precision precision = Precision(precNdx); 11023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const DataType type = typeNdx > 0 ? TYPE_INT : TYPE_UINT; 11033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const string caseName = string(getPrecisionName(precision)) + "_" + getDataTypeName(type); 11043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry group->addChild(new T(context, caseName.c_str(), operandType, type, precision)); 11063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 11073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 11083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return group; 11103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 11113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry catch (...) 11123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 11133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry delete group; 11143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw; 11153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 11163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 11173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11183c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ShaderAtomicOpTests::init (void) 11193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 11203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry addChild(createAtomicOpGroup<ShaderAtomicAddCase> (m_context, m_operandType, "add")); 11213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry addChild(createAtomicOpGroup<ShaderAtomicMinCase> (m_context, m_operandType, "min")); 11223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry addChild(createAtomicOpGroup<ShaderAtomicMaxCase> (m_context, m_operandType, "max")); 11233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry addChild(createAtomicOpGroup<ShaderAtomicAndCase> (m_context, m_operandType, "and")); 11243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry addChild(createAtomicOpGroup<ShaderAtomicOrCase> (m_context, m_operandType, "or")); 11253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry addChild(createAtomicOpGroup<ShaderAtomicXorCase> (m_context, m_operandType, "xor")); 11263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry addChild(createAtomicOpGroup<ShaderAtomicExchangeCase> (m_context, m_operandType, "exchange")); 11273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry addChild(createAtomicOpGroup<ShaderAtomicCompSwapCase> (m_context, m_operandType, "compswap")); 11283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 11293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // Functional 11313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // gles31 11323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // deqp 1133