1e5c31af7Sopenharmony_ci/*------------------------------------------------------------------------ 2e5c31af7Sopenharmony_ci * OpenGL Conformance Tests 3e5c31af7Sopenharmony_ci * ------------------------ 4e5c31af7Sopenharmony_ci * 5e5c31af7Sopenharmony_ci * Copyright (c) 2017-2019 The Khronos Group Inc. 6e5c31af7Sopenharmony_ci * Copyright (c) 2017 Codeplay Software Ltd. 7e5c31af7Sopenharmony_ci * Copyright (c) 2019 NVIDIA Corporation. 8e5c31af7Sopenharmony_ci * 9e5c31af7Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 10e5c31af7Sopenharmony_ci * you may not use this file except in compliance with the License. 11e5c31af7Sopenharmony_ci * You may obtain a copy of the License at 12e5c31af7Sopenharmony_ci * 13e5c31af7Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 14e5c31af7Sopenharmony_ci * 15e5c31af7Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 16e5c31af7Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 17e5c31af7Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18e5c31af7Sopenharmony_ci * See the License for the specific language governing permissions and 19e5c31af7Sopenharmony_ci * limitations under the License. 20e5c31af7Sopenharmony_ci * 21e5c31af7Sopenharmony_ci */ /*! 22e5c31af7Sopenharmony_ci * \file 23e5c31af7Sopenharmony_ci * \brief Subgroups Tests Utils 24e5c31af7Sopenharmony_ci */ /*--------------------------------------------------------------------*/ 25e5c31af7Sopenharmony_ci 26e5c31af7Sopenharmony_ci#include "glcSubgroupsTestsUtils.hpp" 27e5c31af7Sopenharmony_ci#include "deRandom.hpp" 28e5c31af7Sopenharmony_ci#include "tcuCommandLine.hpp" 29e5c31af7Sopenharmony_ci#include "tcuStringTemplate.hpp" 30e5c31af7Sopenharmony_ci#include "gluContextInfo.hpp" 31e5c31af7Sopenharmony_ci#include "gluShaderUtil.hpp" 32e5c31af7Sopenharmony_ci 33e5c31af7Sopenharmony_ciusing namespace deqp; 34e5c31af7Sopenharmony_ciusing namespace std; 35e5c31af7Sopenharmony_ciusing namespace glc; 36e5c31af7Sopenharmony_ciusing namespace glw; 37e5c31af7Sopenharmony_ci 38e5c31af7Sopenharmony_cinamespace 39e5c31af7Sopenharmony_ci{ 40e5c31af7Sopenharmony_ci// debug callback function 41e5c31af7Sopenharmony_ci// To use: 42e5c31af7Sopenharmony_ci// gl.enable(GL_DEBUG_OUTPUT); 43e5c31af7Sopenharmony_ci// gl.debugMessageCallback(debugCallback, &context); 44e5c31af7Sopenharmony_ci// 45e5c31af7Sopenharmony_civoid debugCallback(GLenum source, GLenum type, GLuint id, GLenum severity, 46e5c31af7Sopenharmony_ci GLsizei length, const char * message, const void * userParam) 47e5c31af7Sopenharmony_ci{ 48e5c31af7Sopenharmony_ci glc::Context *context = (glc::Context *)userParam; 49e5c31af7Sopenharmony_ci 50e5c31af7Sopenharmony_ci tcu::TestLog& log = context->getDeqpContext().getTestContext().getLog(); 51e5c31af7Sopenharmony_ci 52e5c31af7Sopenharmony_ci log << tcu::TestLog::Message 53e5c31af7Sopenharmony_ci << "DEBUG: source = " << source << ", type= " << type << ", id = " << id << ", severity = " << severity 54e5c31af7Sopenharmony_ci << ", length = " << length << "\n" 55e5c31af7Sopenharmony_ci << "DEBUG: `" << message << "`" 56e5c31af7Sopenharmony_ci << tcu::TestLog::EndMessage; 57e5c31af7Sopenharmony_ci 58e5c31af7Sopenharmony_ci} 59e5c31af7Sopenharmony_ci 60e5c31af7Sopenharmony_ci// getFormatReadInfo 61e5c31af7Sopenharmony_ci// returns the stride in bytes 62e5c31af7Sopenharmony_cideUint32 getFormatReadInfo(const subgroups::Format format, GLenum &readFormat, GLenum &readType) 63e5c31af7Sopenharmony_ci{ 64e5c31af7Sopenharmony_ci using namespace subgroups; 65e5c31af7Sopenharmony_ci switch (format) 66e5c31af7Sopenharmony_ci { 67e5c31af7Sopenharmony_ci default: 68e5c31af7Sopenharmony_ci DE_FATAL("Unhandled format!"); 69e5c31af7Sopenharmony_ci // fall-through 70e5c31af7Sopenharmony_ci case FORMAT_R32G32B32A32_SFLOAT: 71e5c31af7Sopenharmony_ci readFormat = GL_RGBA; 72e5c31af7Sopenharmony_ci readType = GL_FLOAT; 73e5c31af7Sopenharmony_ci return 4u; 74e5c31af7Sopenharmony_ci case FORMAT_R32G32_SFLOAT: 75e5c31af7Sopenharmony_ci readFormat = GL_RG; 76e5c31af7Sopenharmony_ci readType = GL_FLOAT; 77e5c31af7Sopenharmony_ci return 2u; 78e5c31af7Sopenharmony_ci case FORMAT_R32_UINT: 79e5c31af7Sopenharmony_ci readFormat = GL_RED_INTEGER; 80e5c31af7Sopenharmony_ci readType = GL_UNSIGNED_INT; 81e5c31af7Sopenharmony_ci return 1u; 82e5c31af7Sopenharmony_ci case FORMAT_R32G32B32A32_UINT: 83e5c31af7Sopenharmony_ci readFormat = GL_RGBA_INTEGER; 84e5c31af7Sopenharmony_ci readType = GL_UNSIGNED_INT; 85e5c31af7Sopenharmony_ci return 4u; 86e5c31af7Sopenharmony_ci } 87e5c31af7Sopenharmony_ci} 88e5c31af7Sopenharmony_ci 89e5c31af7Sopenharmony_cideUint32 getMaxWidth () 90e5c31af7Sopenharmony_ci{ 91e5c31af7Sopenharmony_ci return 1024u; 92e5c31af7Sopenharmony_ci} 93e5c31af7Sopenharmony_ci 94e5c31af7Sopenharmony_cideUint32 getNextWidth (const deUint32 width) 95e5c31af7Sopenharmony_ci{ 96e5c31af7Sopenharmony_ci if (width < 128) 97e5c31af7Sopenharmony_ci { 98e5c31af7Sopenharmony_ci // This ensures we test every value up to 128 (the max subgroup size). 99e5c31af7Sopenharmony_ci return width + 1; 100e5c31af7Sopenharmony_ci } 101e5c31af7Sopenharmony_ci else 102e5c31af7Sopenharmony_ci { 103e5c31af7Sopenharmony_ci // And once we hit 128 we increment to only power of 2's to reduce testing time. 104e5c31af7Sopenharmony_ci return width * 2; 105e5c31af7Sopenharmony_ci } 106e5c31af7Sopenharmony_ci} 107e5c31af7Sopenharmony_ci 108e5c31af7Sopenharmony_cideUint32 getFormatSizeInBytes(const subgroups::Format format) 109e5c31af7Sopenharmony_ci{ 110e5c31af7Sopenharmony_ci using namespace subgroups; 111e5c31af7Sopenharmony_ci switch (format) 112e5c31af7Sopenharmony_ci { 113e5c31af7Sopenharmony_ci default: 114e5c31af7Sopenharmony_ci DE_FATAL("Unhandled format!"); 115e5c31af7Sopenharmony_ci return 0; 116e5c31af7Sopenharmony_ci case FORMAT_R32_SINT: 117e5c31af7Sopenharmony_ci case FORMAT_R32_UINT: 118e5c31af7Sopenharmony_ci return sizeof(deInt32); 119e5c31af7Sopenharmony_ci case FORMAT_R32G32_SINT: 120e5c31af7Sopenharmony_ci case FORMAT_R32G32_UINT: 121e5c31af7Sopenharmony_ci return static_cast<deUint32>(sizeof(deInt32) * 2); 122e5c31af7Sopenharmony_ci case FORMAT_R32G32B32_SINT: 123e5c31af7Sopenharmony_ci case FORMAT_R32G32B32_UINT: 124e5c31af7Sopenharmony_ci case FORMAT_R32G32B32A32_SINT: 125e5c31af7Sopenharmony_ci case FORMAT_R32G32B32A32_UINT: 126e5c31af7Sopenharmony_ci return static_cast<deUint32>(sizeof(deInt32) * 4); 127e5c31af7Sopenharmony_ci case FORMAT_R32_SFLOAT: 128e5c31af7Sopenharmony_ci return 4; 129e5c31af7Sopenharmony_ci case FORMAT_R32G32_SFLOAT: 130e5c31af7Sopenharmony_ci return 8; 131e5c31af7Sopenharmony_ci case FORMAT_R32G32B32_SFLOAT: 132e5c31af7Sopenharmony_ci return 16; 133e5c31af7Sopenharmony_ci case FORMAT_R32G32B32A32_SFLOAT: 134e5c31af7Sopenharmony_ci return 16; 135e5c31af7Sopenharmony_ci case FORMAT_R64_SFLOAT: 136e5c31af7Sopenharmony_ci return 8; 137e5c31af7Sopenharmony_ci case FORMAT_R64G64_SFLOAT: 138e5c31af7Sopenharmony_ci return 16; 139e5c31af7Sopenharmony_ci case FORMAT_R64G64B64_SFLOAT: 140e5c31af7Sopenharmony_ci return 32; 141e5c31af7Sopenharmony_ci case FORMAT_R64G64B64A64_SFLOAT: 142e5c31af7Sopenharmony_ci return 32; 143e5c31af7Sopenharmony_ci // The below formats are used to represent bool and bvec* types. These 144e5c31af7Sopenharmony_ci // types are passed to the shader as int and ivec* types, before the 145e5c31af7Sopenharmony_ci // calculations are done as booleans. We need a distinct type here so 146e5c31af7Sopenharmony_ci // that the shader generators can switch on it and generate the correct 147e5c31af7Sopenharmony_ci // shader source for testing. 148e5c31af7Sopenharmony_ci case FORMAT_R32_BOOL: 149e5c31af7Sopenharmony_ci return sizeof(deInt32); 150e5c31af7Sopenharmony_ci case FORMAT_R32G32_BOOL: 151e5c31af7Sopenharmony_ci return static_cast<deUint32>(sizeof(deInt32) * 2); 152e5c31af7Sopenharmony_ci case FORMAT_R32G32B32_BOOL: 153e5c31af7Sopenharmony_ci case FORMAT_R32G32B32A32_BOOL: 154e5c31af7Sopenharmony_ci return static_cast<deUint32>(sizeof(deInt32) * 4); 155e5c31af7Sopenharmony_ci } 156e5c31af7Sopenharmony_ci} 157e5c31af7Sopenharmony_ci 158e5c31af7Sopenharmony_cideUint32 getElementSizeInBytes( 159e5c31af7Sopenharmony_ci const subgroups::Format format, 160e5c31af7Sopenharmony_ci const subgroups::SSBOData::InputDataLayoutType layout) 161e5c31af7Sopenharmony_ci{ 162e5c31af7Sopenharmony_ci deUint32 bytes = getFormatSizeInBytes(format); 163e5c31af7Sopenharmony_ci if (layout == subgroups::SSBOData::LayoutStd140) 164e5c31af7Sopenharmony_ci return bytes < 16 ? 16 : bytes; 165e5c31af7Sopenharmony_ci else 166e5c31af7Sopenharmony_ci return bytes; 167e5c31af7Sopenharmony_ci} 168e5c31af7Sopenharmony_ci 169e5c31af7Sopenharmony_ci 170e5c31af7Sopenharmony_cide::MovePtr<glu::ShaderProgram> makeGraphicsPipeline(glc::Context& context, 171e5c31af7Sopenharmony_ci const subgroups::ShaderStageFlags stages, 172e5c31af7Sopenharmony_ci const GlslSource * vshader, 173e5c31af7Sopenharmony_ci const GlslSource * fshader, 174e5c31af7Sopenharmony_ci const GlslSource * gshader, 175e5c31af7Sopenharmony_ci const GlslSource * tcshader, 176e5c31af7Sopenharmony_ci const GlslSource * teshader) 177e5c31af7Sopenharmony_ci{ 178e5c31af7Sopenharmony_ci tcu::TestLog& log = context.getDeqpContext().getTestContext().getLog(); 179e5c31af7Sopenharmony_ci const bool doShaderLog = log.isShaderLoggingEnabled(); 180e5c31af7Sopenharmony_ci DE_UNREF(stages); // only used for asserts 181e5c31af7Sopenharmony_ci 182e5c31af7Sopenharmony_ci map<string, string> templateArgs; 183e5c31af7Sopenharmony_ci string versionDecl(getGLSLVersionDeclaration(context.getGLSLVersion())); 184e5c31af7Sopenharmony_ci string tessExtension = 185e5c31af7Sopenharmony_ci context.getDeqpContext().getContextInfo().isExtensionSupported("GL_EXT_tessellation_shader") ? 186e5c31af7Sopenharmony_ci "#extension GL_EXT_tessellation_shader : require" : 187e5c31af7Sopenharmony_ci ""; 188e5c31af7Sopenharmony_ci templateArgs.insert(pair<string, string>("VERSION_DECL", versionDecl)); 189e5c31af7Sopenharmony_ci templateArgs.insert(pair<string, string>("TESS_EXTENSION", tessExtension)); 190e5c31af7Sopenharmony_ci 191e5c31af7Sopenharmony_ci string vertSource, tescSource, teseSource, geomSource, fragSource; 192e5c31af7Sopenharmony_ci if (vshader) 193e5c31af7Sopenharmony_ci { 194e5c31af7Sopenharmony_ci DE_ASSERT(stages & subgroups::SHADER_STAGE_VERTEX_BIT); 195e5c31af7Sopenharmony_ci tcu::StringTemplate shaderTemplate(vshader->sources[glu::SHADERTYPE_VERTEX][0]); 196e5c31af7Sopenharmony_ci string shaderSource(shaderTemplate.specialize(templateArgs)); 197e5c31af7Sopenharmony_ci if (doShaderLog) 198e5c31af7Sopenharmony_ci { 199e5c31af7Sopenharmony_ci log << tcu::TestLog::Message << "vertex shader:\n" 200e5c31af7Sopenharmony_ci << shaderSource << "\n:end:" << tcu::TestLog::EndMessage; 201e5c31af7Sopenharmony_ci } 202e5c31af7Sopenharmony_ci vertSource = shaderSource; 203e5c31af7Sopenharmony_ci } 204e5c31af7Sopenharmony_ci if (tcshader) 205e5c31af7Sopenharmony_ci { 206e5c31af7Sopenharmony_ci DE_ASSERT(stages & subgroups::SHADER_STAGE_TESS_CONTROL_BIT); 207e5c31af7Sopenharmony_ci tcu::StringTemplate shaderTemplate(tcshader->sources[glu::SHADERTYPE_TESSELLATION_CONTROL][0]); 208e5c31af7Sopenharmony_ci string shaderSource(shaderTemplate.specialize(templateArgs)); 209e5c31af7Sopenharmony_ci if (doShaderLog) 210e5c31af7Sopenharmony_ci { 211e5c31af7Sopenharmony_ci log << tcu::TestLog::Message << "tess control shader:\n" 212e5c31af7Sopenharmony_ci << shaderSource << "\n:end:" << tcu::TestLog::EndMessage; 213e5c31af7Sopenharmony_ci } 214e5c31af7Sopenharmony_ci tescSource = shaderSource; 215e5c31af7Sopenharmony_ci } 216e5c31af7Sopenharmony_ci if (teshader) 217e5c31af7Sopenharmony_ci { 218e5c31af7Sopenharmony_ci DE_ASSERT(stages & subgroups::SHADER_STAGE_TESS_EVALUATION_BIT); 219e5c31af7Sopenharmony_ci tcu::StringTemplate shaderTemplate(teshader->sources[glu::SHADERTYPE_TESSELLATION_EVALUATION][0]); 220e5c31af7Sopenharmony_ci string shaderSource(shaderTemplate.specialize(templateArgs)); 221e5c31af7Sopenharmony_ci if (doShaderLog) 222e5c31af7Sopenharmony_ci { 223e5c31af7Sopenharmony_ci log << tcu::TestLog::Message << "tess eval shader:\n" 224e5c31af7Sopenharmony_ci << shaderSource << "\n:end:" << tcu::TestLog::EndMessage; 225e5c31af7Sopenharmony_ci } 226e5c31af7Sopenharmony_ci teseSource = shaderSource; 227e5c31af7Sopenharmony_ci } 228e5c31af7Sopenharmony_ci if (gshader) 229e5c31af7Sopenharmony_ci { 230e5c31af7Sopenharmony_ci DE_ASSERT(stages & subgroups::SHADER_STAGE_GEOMETRY_BIT); 231e5c31af7Sopenharmony_ci tcu::StringTemplate shaderTemplate(gshader->sources[glu::SHADERTYPE_GEOMETRY][0]); 232e5c31af7Sopenharmony_ci string shaderSource(shaderTemplate.specialize(templateArgs)); 233e5c31af7Sopenharmony_ci if (doShaderLog) 234e5c31af7Sopenharmony_ci { 235e5c31af7Sopenharmony_ci log << tcu::TestLog::Message << "geometry shader:\n" 236e5c31af7Sopenharmony_ci << shaderSource << "\n:end:" << tcu::TestLog::EndMessage; 237e5c31af7Sopenharmony_ci } 238e5c31af7Sopenharmony_ci geomSource = shaderSource; 239e5c31af7Sopenharmony_ci } 240e5c31af7Sopenharmony_ci if (fshader) 241e5c31af7Sopenharmony_ci { 242e5c31af7Sopenharmony_ci DE_ASSERT(stages & subgroups::SHADER_STAGE_FRAGMENT_BIT); 243e5c31af7Sopenharmony_ci tcu::StringTemplate shaderTemplate(fshader->sources[glu::SHADERTYPE_FRAGMENT][0]); 244e5c31af7Sopenharmony_ci string shaderSource(shaderTemplate.specialize(templateArgs)); 245e5c31af7Sopenharmony_ci if (doShaderLog) 246e5c31af7Sopenharmony_ci { 247e5c31af7Sopenharmony_ci log << tcu::TestLog::Message << "fragment shader:\n" 248e5c31af7Sopenharmony_ci << shaderSource << "\n:end:" << tcu::TestLog::EndMessage; 249e5c31af7Sopenharmony_ci } 250e5c31af7Sopenharmony_ci fragSource = shaderSource; 251e5c31af7Sopenharmony_ci } 252e5c31af7Sopenharmony_ci 253e5c31af7Sopenharmony_ci glu::ShaderProgram *program = DE_NULL; 254e5c31af7Sopenharmony_ci if(context.getShaderType() == SHADER_TYPE_GLSL) 255e5c31af7Sopenharmony_ci { 256e5c31af7Sopenharmony_ci glu::ProgramSources sources; 257e5c31af7Sopenharmony_ci if (vshader) 258e5c31af7Sopenharmony_ci sources << glu::VertexSource(vertSource); 259e5c31af7Sopenharmony_ci if (tcshader) 260e5c31af7Sopenharmony_ci sources << glu::TessellationControlSource(tescSource); 261e5c31af7Sopenharmony_ci if (teshader) 262e5c31af7Sopenharmony_ci sources << glu::TessellationEvaluationSource(teseSource); 263e5c31af7Sopenharmony_ci if (gshader) 264e5c31af7Sopenharmony_ci sources << glu::GeometrySource(geomSource); 265e5c31af7Sopenharmony_ci if (fshader) 266e5c31af7Sopenharmony_ci sources << glu::FragmentSource(fragSource); 267e5c31af7Sopenharmony_ci 268e5c31af7Sopenharmony_ci program = new glu::ShaderProgram(context.getDeqpContext().getRenderContext().getFunctions(), sources); 269e5c31af7Sopenharmony_ci } else { 270e5c31af7Sopenharmony_ci DE_ASSERT(context.getShaderType() == SHADER_TYPE_SPIRV); 271e5c31af7Sopenharmony_ci 272e5c31af7Sopenharmony_ci glu::ProgramBinaries binaries; 273e5c31af7Sopenharmony_ci if (vshader) 274e5c31af7Sopenharmony_ci binaries << spirvUtils::makeSpirV(log, glu::VertexSource(vertSource), spirvUtils::SPIRV_VERSION_1_3); 275e5c31af7Sopenharmony_ci if (tcshader) 276e5c31af7Sopenharmony_ci binaries << spirvUtils::makeSpirV(log, glu::TessellationControlSource(tescSource), spirvUtils::SPIRV_VERSION_1_3); 277e5c31af7Sopenharmony_ci if (teshader) 278e5c31af7Sopenharmony_ci binaries << spirvUtils::makeSpirV(log, glu::TessellationEvaluationSource(teseSource), spirvUtils::SPIRV_VERSION_1_3); 279e5c31af7Sopenharmony_ci if (gshader) 280e5c31af7Sopenharmony_ci binaries << spirvUtils::makeSpirV(log, glu::GeometrySource(geomSource), spirvUtils::SPIRV_VERSION_1_3); 281e5c31af7Sopenharmony_ci if (fshader) 282e5c31af7Sopenharmony_ci binaries << spirvUtils::makeSpirV(log, glu::FragmentSource(fragSource), spirvUtils::SPIRV_VERSION_1_3); 283e5c31af7Sopenharmony_ci 284e5c31af7Sopenharmony_ci program = new glu::ShaderProgram(context.getDeqpContext().getRenderContext().getFunctions(), binaries); 285e5c31af7Sopenharmony_ci } 286e5c31af7Sopenharmony_ci 287e5c31af7Sopenharmony_ci if (!program->isOk()) 288e5c31af7Sopenharmony_ci { 289e5c31af7Sopenharmony_ci log << tcu::TestLog::Message << "Shader build failed.\n" 290e5c31af7Sopenharmony_ci << "Vertex: " << (vshader ? program->getShaderInfo(glu::SHADERTYPE_VERTEX).infoLog : "n/a") << "\n" 291e5c31af7Sopenharmony_ci << "Tess Cont: " << (tcshader ? program->getShaderInfo(glu::SHADERTYPE_TESSELLATION_CONTROL).infoLog : "n/a") << "\n" 292e5c31af7Sopenharmony_ci << "Tess Eval: " << (teshader ? program->getShaderInfo(glu::SHADERTYPE_TESSELLATION_EVALUATION).infoLog : "n/a") << "\n" 293e5c31af7Sopenharmony_ci << "Geometry: " << (gshader ? program->getShaderInfo(glu::SHADERTYPE_GEOMETRY).infoLog : "n/a") << "\n" 294e5c31af7Sopenharmony_ci << "Fragment: " << (fshader ? program->getShaderInfo(glu::SHADERTYPE_FRAGMENT).infoLog : "n/a") << "\n" 295e5c31af7Sopenharmony_ci << "Program: " << program->getProgramInfo().infoLog << tcu::TestLog::EndMessage; 296e5c31af7Sopenharmony_ci } 297e5c31af7Sopenharmony_ci return de::MovePtr<glu::ShaderProgram>(program); 298e5c31af7Sopenharmony_ci} 299e5c31af7Sopenharmony_ci 300e5c31af7Sopenharmony_cide::MovePtr<glu::ShaderProgram> makeComputePipeline(glc::Context& context, const GlslSource &glslTemplate, 301e5c31af7Sopenharmony_ci deUint32 localSizeX, deUint32 localSizeY, deUint32 localSizeZ) 302e5c31af7Sopenharmony_ci{ 303e5c31af7Sopenharmony_ci 304e5c31af7Sopenharmony_ci tcu::TestLog& log = context.getDeqpContext().getTestContext().getLog(); 305e5c31af7Sopenharmony_ci const bool doShaderLog = log.isShaderLoggingEnabled(); 306e5c31af7Sopenharmony_ci 307e5c31af7Sopenharmony_ci tcu::StringTemplate computeTemplate(glslTemplate.sources[glu::SHADERTYPE_COMPUTE][0]); 308e5c31af7Sopenharmony_ci 309e5c31af7Sopenharmony_ci map<string, string> templateArgs; 310e5c31af7Sopenharmony_ci { 311e5c31af7Sopenharmony_ci stringstream localSize; 312e5c31af7Sopenharmony_ci localSize << "local_size_x = " << localSizeX; 313e5c31af7Sopenharmony_ci templateArgs.insert(pair<string, string>("LOCAL_SIZE_X", localSize.str())); 314e5c31af7Sopenharmony_ci } 315e5c31af7Sopenharmony_ci { 316e5c31af7Sopenharmony_ci stringstream localSize; 317e5c31af7Sopenharmony_ci localSize << "local_size_y = " << localSizeY; 318e5c31af7Sopenharmony_ci templateArgs.insert(pair<string, string>("LOCAL_SIZE_Y", localSize.str())); 319e5c31af7Sopenharmony_ci } 320e5c31af7Sopenharmony_ci { 321e5c31af7Sopenharmony_ci stringstream localSize; 322e5c31af7Sopenharmony_ci localSize << "local_size_z = " << localSizeZ; 323e5c31af7Sopenharmony_ci templateArgs.insert(pair<string, string>("LOCAL_SIZE_Z", localSize.str())); 324e5c31af7Sopenharmony_ci } 325e5c31af7Sopenharmony_ci string versionDecl(getGLSLVersionDeclaration(context.getGLSLVersion())); 326e5c31af7Sopenharmony_ci templateArgs.insert(pair<string, string>("VERSION_DECL", versionDecl)); 327e5c31af7Sopenharmony_ci 328e5c31af7Sopenharmony_ci glu::ComputeSource cshader(glu::ComputeSource(computeTemplate.specialize(templateArgs))); 329e5c31af7Sopenharmony_ci 330e5c31af7Sopenharmony_ci if (doShaderLog) 331e5c31af7Sopenharmony_ci { 332e5c31af7Sopenharmony_ci log << tcu::TestLog::Message << "compute shader specialized source:\n" 333e5c31af7Sopenharmony_ci << cshader.source << "\n:end:" << tcu::TestLog::EndMessage; 334e5c31af7Sopenharmony_ci } 335e5c31af7Sopenharmony_ci 336e5c31af7Sopenharmony_ci glu::ShaderProgram *program = DE_NULL; 337e5c31af7Sopenharmony_ci if(context.getShaderType() == SHADER_TYPE_GLSL) 338e5c31af7Sopenharmony_ci { 339e5c31af7Sopenharmony_ci glu::ProgramSources sources; 340e5c31af7Sopenharmony_ci sources << cshader; 341e5c31af7Sopenharmony_ci program = new glu::ShaderProgram(context.getDeqpContext().getRenderContext().getFunctions(), sources); 342e5c31af7Sopenharmony_ci } else { 343e5c31af7Sopenharmony_ci DE_ASSERT(context.getShaderType() == SHADER_TYPE_SPIRV); 344e5c31af7Sopenharmony_ci 345e5c31af7Sopenharmony_ci glu::ProgramBinaries binaries; 346e5c31af7Sopenharmony_ci binaries << spirvUtils::makeSpirV(log, cshader, spirvUtils::SPIRV_VERSION_1_3); 347e5c31af7Sopenharmony_ci 348e5c31af7Sopenharmony_ci program = new glu::ShaderProgram(context.getDeqpContext().getRenderContext().getFunctions(), binaries); 349e5c31af7Sopenharmony_ci } 350e5c31af7Sopenharmony_ci 351e5c31af7Sopenharmony_ci if (!program->isOk()) 352e5c31af7Sopenharmony_ci { 353e5c31af7Sopenharmony_ci log << tcu::TestLog::Message << "Shader build failed.\n" 354e5c31af7Sopenharmony_ci << "Compute: " << program->getShaderInfo(glu::SHADERTYPE_COMPUTE).infoLog << "\n" 355e5c31af7Sopenharmony_ci << "Program: " << program->getProgramInfo().infoLog << tcu::TestLog::EndMessage; 356e5c31af7Sopenharmony_ci } 357e5c31af7Sopenharmony_ci return de::MovePtr<glu::ShaderProgram>(program); 358e5c31af7Sopenharmony_ci} 359e5c31af7Sopenharmony_ci 360e5c31af7Sopenharmony_cistruct Buffer; 361e5c31af7Sopenharmony_cistruct Image; 362e5c31af7Sopenharmony_ci 363e5c31af7Sopenharmony_cistruct BufferOrImage 364e5c31af7Sopenharmony_ci{ 365e5c31af7Sopenharmony_ci bool isImage() const 366e5c31af7Sopenharmony_ci { 367e5c31af7Sopenharmony_ci return m_isImage; 368e5c31af7Sopenharmony_ci } 369e5c31af7Sopenharmony_ci 370e5c31af7Sopenharmony_ci Buffer* getAsBuffer() 371e5c31af7Sopenharmony_ci { 372e5c31af7Sopenharmony_ci if (m_isImage) DE_FATAL("Trying to get a buffer as an image!"); 373e5c31af7Sopenharmony_ci return reinterpret_cast<Buffer* >(this); 374e5c31af7Sopenharmony_ci } 375e5c31af7Sopenharmony_ci 376e5c31af7Sopenharmony_ci Image* getAsImage() 377e5c31af7Sopenharmony_ci { 378e5c31af7Sopenharmony_ci if (!m_isImage) DE_FATAL("Trying to get an image as a buffer!"); 379e5c31af7Sopenharmony_ci return reinterpret_cast<Image*>(this); 380e5c31af7Sopenharmony_ci } 381e5c31af7Sopenharmony_ci 382e5c31af7Sopenharmony_ci virtual subgroups::DescriptorType getType() const 383e5c31af7Sopenharmony_ci { 384e5c31af7Sopenharmony_ci if (m_isImage) 385e5c31af7Sopenharmony_ci { 386e5c31af7Sopenharmony_ci return subgroups::DESCRIPTOR_TYPE_STORAGE_IMAGE; 387e5c31af7Sopenharmony_ci } 388e5c31af7Sopenharmony_ci else 389e5c31af7Sopenharmony_ci { 390e5c31af7Sopenharmony_ci return subgroups::DESCRIPTOR_TYPE_STORAGE_BUFFER; 391e5c31af7Sopenharmony_ci } 392e5c31af7Sopenharmony_ci } 393e5c31af7Sopenharmony_ci 394e5c31af7Sopenharmony_ci GLuint getId() 395e5c31af7Sopenharmony_ci { 396e5c31af7Sopenharmony_ci return m_objectId; 397e5c31af7Sopenharmony_ci } 398e5c31af7Sopenharmony_ci 399e5c31af7Sopenharmony_ci virtual ~BufferOrImage() {} 400e5c31af7Sopenharmony_ci 401e5c31af7Sopenharmony_ciprotected: 402e5c31af7Sopenharmony_ci explicit BufferOrImage(glc::Context& context, bool image) 403e5c31af7Sopenharmony_ci : m_gl(context.getDeqpContext().getRenderContext().getFunctions()) 404e5c31af7Sopenharmony_ci , m_isImage(image) 405e5c31af7Sopenharmony_ci , m_objectId(0) {} 406e5c31af7Sopenharmony_ci 407e5c31af7Sopenharmony_ci const glw::Functions & m_gl; 408e5c31af7Sopenharmony_ci bool m_isImage; 409e5c31af7Sopenharmony_ci GLuint m_objectId; 410e5c31af7Sopenharmony_ci}; 411e5c31af7Sopenharmony_ci 412e5c31af7Sopenharmony_cistruct Buffer : public BufferOrImage 413e5c31af7Sopenharmony_ci{ 414e5c31af7Sopenharmony_ci explicit Buffer( 415e5c31af7Sopenharmony_ci glc::Context& context, deUint64 sizeInBytes, GLenum target = GL_SHADER_STORAGE_BUFFER) 416e5c31af7Sopenharmony_ci : BufferOrImage (context, false) 417e5c31af7Sopenharmony_ci , m_sizeInBytes (sizeInBytes) 418e5c31af7Sopenharmony_ci , m_target (target) 419e5c31af7Sopenharmony_ci { 420e5c31af7Sopenharmony_ci m_gl.genBuffers(1, &m_objectId); 421e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(m_gl.getError(), "genBuffers"); 422e5c31af7Sopenharmony_ci m_gl.bindBuffer(m_target, m_objectId); 423e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(m_gl.getError(), "bindBuffer"); 424e5c31af7Sopenharmony_ci m_gl.bufferData(m_target, m_sizeInBytes, NULL, GL_DYNAMIC_DRAW); 425e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(m_gl.getError(), "bufferData"); 426e5c31af7Sopenharmony_ci m_gl.bindBuffer(m_target, 0); 427e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(m_gl.getError(), "bindBuffer(0)"); 428e5c31af7Sopenharmony_ci } 429e5c31af7Sopenharmony_ci 430e5c31af7Sopenharmony_ci virtual ~Buffer() 431e5c31af7Sopenharmony_ci { 432e5c31af7Sopenharmony_ci if (m_objectId != 0) 433e5c31af7Sopenharmony_ci { 434e5c31af7Sopenharmony_ci m_gl.deleteBuffers(1, &m_objectId); 435e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(m_gl.getError(), "glDeleteBuffers"); 436e5c31af7Sopenharmony_ci } 437e5c31af7Sopenharmony_ci } 438e5c31af7Sopenharmony_ci 439e5c31af7Sopenharmony_ci virtual subgroups::DescriptorType getType() const 440e5c31af7Sopenharmony_ci { 441e5c31af7Sopenharmony_ci if (GL_UNIFORM_BUFFER == m_target) 442e5c31af7Sopenharmony_ci { 443e5c31af7Sopenharmony_ci return subgroups::DESCRIPTOR_TYPE_UNIFORM_BUFFER; 444e5c31af7Sopenharmony_ci } 445e5c31af7Sopenharmony_ci return subgroups::DESCRIPTOR_TYPE_STORAGE_BUFFER; 446e5c31af7Sopenharmony_ci } 447e5c31af7Sopenharmony_ci 448e5c31af7Sopenharmony_ci glw::GLvoid* mapBufferPtr() { 449e5c31af7Sopenharmony_ci glw::GLvoid *ptr; 450e5c31af7Sopenharmony_ci 451e5c31af7Sopenharmony_ci m_gl.bindBuffer(m_target, m_objectId); 452e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindBuffer"); 453e5c31af7Sopenharmony_ci 454e5c31af7Sopenharmony_ci ptr = m_gl.mapBufferRange(m_target, 0, m_sizeInBytes, GL_MAP_READ_BIT | GL_MAP_WRITE_BIT); 455e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(m_gl.getError(), "glMapBuffer"); 456e5c31af7Sopenharmony_ci 457e5c31af7Sopenharmony_ci m_gl.bindBuffer(m_target, 0); 458e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindBuffer(0)"); 459e5c31af7Sopenharmony_ci 460e5c31af7Sopenharmony_ci return ptr; 461e5c31af7Sopenharmony_ci } 462e5c31af7Sopenharmony_ci 463e5c31af7Sopenharmony_ci void unmapBufferPtr() { 464e5c31af7Sopenharmony_ci m_gl.bindBuffer(m_target, m_objectId); 465e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindBuffer"); 466e5c31af7Sopenharmony_ci 467e5c31af7Sopenharmony_ci m_gl.unmapBuffer(m_target); 468e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(m_gl.getError(), "glUnmapBuffer"); 469e5c31af7Sopenharmony_ci 470e5c31af7Sopenharmony_ci m_gl.bindBuffer(m_target, 0); 471e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindBuffer(0)"); 472e5c31af7Sopenharmony_ci } 473e5c31af7Sopenharmony_ci 474e5c31af7Sopenharmony_ci deUint64 getSize() const { 475e5c31af7Sopenharmony_ci return m_sizeInBytes; 476e5c31af7Sopenharmony_ci } 477e5c31af7Sopenharmony_ci 478e5c31af7Sopenharmony_ciprivate: 479e5c31af7Sopenharmony_ci deUint64 m_sizeInBytes; 480e5c31af7Sopenharmony_ci const GLenum m_target; 481e5c31af7Sopenharmony_ci}; 482e5c31af7Sopenharmony_ci 483e5c31af7Sopenharmony_cistruct Image : public BufferOrImage 484e5c31af7Sopenharmony_ci{ 485e5c31af7Sopenharmony_ci explicit Image(glc::Context& context, deUint32 width, deUint32 height, 486e5c31af7Sopenharmony_ci subgroups::Format format) 487e5c31af7Sopenharmony_ci : BufferOrImage(context, true) 488e5c31af7Sopenharmony_ci { 489e5c31af7Sopenharmony_ci m_gl.genTextures(1, &m_objectId); 490e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(m_gl.getError(), "glGenTextures"); 491e5c31af7Sopenharmony_ci m_gl.bindTexture(GL_TEXTURE_2D, m_objectId); 492e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindTexture"); 493e5c31af7Sopenharmony_ci m_gl.texStorage2D(GL_TEXTURE_2D, 1, format, width, height); 494e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(m_gl.getError(), "glTexStorage2D"); 495e5c31af7Sopenharmony_ci 496e5c31af7Sopenharmony_ci m_gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 497e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(m_gl.getError(), "glTexParameteri"); 498e5c31af7Sopenharmony_ci m_gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 499e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(m_gl.getError(), "glTexParameteri"); 500e5c31af7Sopenharmony_ci } 501e5c31af7Sopenharmony_ci 502e5c31af7Sopenharmony_ci virtual ~Image() 503e5c31af7Sopenharmony_ci { 504e5c31af7Sopenharmony_ci if (m_objectId != 0) 505e5c31af7Sopenharmony_ci { 506e5c31af7Sopenharmony_ci m_gl.deleteTextures(1, &m_objectId); 507e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(m_gl.getError(), "glDeleteTextures"); 508e5c31af7Sopenharmony_ci } 509e5c31af7Sopenharmony_ci } 510e5c31af7Sopenharmony_ci 511e5c31af7Sopenharmony_ciprivate: 512e5c31af7Sopenharmony_ci}; 513e5c31af7Sopenharmony_ci 514e5c31af7Sopenharmony_cistruct Vao 515e5c31af7Sopenharmony_ci{ 516e5c31af7Sopenharmony_ci explicit Vao(glc::Context& context) 517e5c31af7Sopenharmony_ci : m_gl(context.getDeqpContext().getRenderContext().getFunctions()) 518e5c31af7Sopenharmony_ci , m_objectId(0) 519e5c31af7Sopenharmony_ci { 520e5c31af7Sopenharmony_ci m_gl.genVertexArrays(1, &m_objectId); 521e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(m_gl.getError(), "glGenVertexArrays"); 522e5c31af7Sopenharmony_ci m_gl.bindVertexArray(m_objectId); 523e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindVertexArray"); 524e5c31af7Sopenharmony_ci } 525e5c31af7Sopenharmony_ci 526e5c31af7Sopenharmony_ci ~Vao() 527e5c31af7Sopenharmony_ci { 528e5c31af7Sopenharmony_ci if (m_objectId != 0) 529e5c31af7Sopenharmony_ci { 530e5c31af7Sopenharmony_ci m_gl.deleteVertexArrays(1, &m_objectId); 531e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(m_gl.getError(), "glDeleteVertexArrays"); 532e5c31af7Sopenharmony_ci } 533e5c31af7Sopenharmony_ci } 534e5c31af7Sopenharmony_ci 535e5c31af7Sopenharmony_ciprivate: 536e5c31af7Sopenharmony_ci const glw::Functions & m_gl; 537e5c31af7Sopenharmony_ci GLuint m_objectId; 538e5c31af7Sopenharmony_ci}; 539e5c31af7Sopenharmony_ci 540e5c31af7Sopenharmony_cistruct Fbo 541e5c31af7Sopenharmony_ci{ 542e5c31af7Sopenharmony_ci explicit Fbo(glc::Context& context) 543e5c31af7Sopenharmony_ci : m_gl(context.getDeqpContext().getRenderContext().getFunctions()) 544e5c31af7Sopenharmony_ci , m_objectId(0) 545e5c31af7Sopenharmony_ci { 546e5c31af7Sopenharmony_ci m_gl.genFramebuffers(1, &m_objectId); 547e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(m_gl.getError(), "glGenFramebuffers"); 548e5c31af7Sopenharmony_ci m_gl.bindFramebuffer(GL_FRAMEBUFFER, m_objectId); 549e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindFramebuffer"); 550e5c31af7Sopenharmony_ci } 551e5c31af7Sopenharmony_ci 552e5c31af7Sopenharmony_ci ~Fbo() 553e5c31af7Sopenharmony_ci { 554e5c31af7Sopenharmony_ci if (m_objectId != 0) 555e5c31af7Sopenharmony_ci { 556e5c31af7Sopenharmony_ci m_gl.deleteFramebuffers(1, &m_objectId); 557e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(m_gl.getError(), "deleteFramebuffers"); 558e5c31af7Sopenharmony_ci } 559e5c31af7Sopenharmony_ci } 560e5c31af7Sopenharmony_ci 561e5c31af7Sopenharmony_ci void bind2D(Image &img) 562e5c31af7Sopenharmony_ci { 563e5c31af7Sopenharmony_ci m_gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, img.getId(), 0); 564e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(m_gl.getError(), "glFramebufferTexture2D"); 565e5c31af7Sopenharmony_ci } 566e5c31af7Sopenharmony_ci 567e5c31af7Sopenharmony_ciprivate: 568e5c31af7Sopenharmony_ci const glw::Functions & m_gl; 569e5c31af7Sopenharmony_ci GLuint m_objectId; 570e5c31af7Sopenharmony_ci 571e5c31af7Sopenharmony_ci}; 572e5c31af7Sopenharmony_ci} 573e5c31af7Sopenharmony_ci 574e5c31af7Sopenharmony_cistd::string glc::subgroups::getSharedMemoryBallotHelper() 575e5c31af7Sopenharmony_ci{ 576e5c31af7Sopenharmony_ci return "shared uvec4 superSecretComputeShaderHelper[gl_WorkGroupSize.x * gl_WorkGroupSize.y * gl_WorkGroupSize.z];\n" 577e5c31af7Sopenharmony_ci "uvec4 sharedMemoryBallot(bool vote)\n" 578e5c31af7Sopenharmony_ci "{\n" 579e5c31af7Sopenharmony_ci " uint groupOffset = gl_SubgroupID;\n" 580e5c31af7Sopenharmony_ci " // One invocation in the group 0's the whole group's data\n" 581e5c31af7Sopenharmony_ci " if (subgroupElect())\n" 582e5c31af7Sopenharmony_ci " {\n" 583e5c31af7Sopenharmony_ci " superSecretComputeShaderHelper[groupOffset] = uvec4(0);\n" 584e5c31af7Sopenharmony_ci " }\n" 585e5c31af7Sopenharmony_ci " subgroupMemoryBarrierShared();\n" 586e5c31af7Sopenharmony_ci " if (vote)\n" 587e5c31af7Sopenharmony_ci " {\n" 588e5c31af7Sopenharmony_ci " highp uint invocationId = gl_SubgroupInvocationID % 32u;\n" 589e5c31af7Sopenharmony_ci " highp uint bitToSet = 1u << invocationId;\n" 590e5c31af7Sopenharmony_ci " switch (gl_SubgroupInvocationID / 32u)\n" 591e5c31af7Sopenharmony_ci " {\n" 592e5c31af7Sopenharmony_ci " case 0u: atomicOr(superSecretComputeShaderHelper[groupOffset].x, bitToSet); break;\n" 593e5c31af7Sopenharmony_ci " case 1u: atomicOr(superSecretComputeShaderHelper[groupOffset].y, bitToSet); break;\n" 594e5c31af7Sopenharmony_ci " case 2u: atomicOr(superSecretComputeShaderHelper[groupOffset].z, bitToSet); break;\n" 595e5c31af7Sopenharmony_ci " case 3u: atomicOr(superSecretComputeShaderHelper[groupOffset].w, bitToSet); break;\n" 596e5c31af7Sopenharmony_ci " }\n" 597e5c31af7Sopenharmony_ci " }\n" 598e5c31af7Sopenharmony_ci " subgroupMemoryBarrierShared();\n" 599e5c31af7Sopenharmony_ci " return superSecretComputeShaderHelper[groupOffset];\n" 600e5c31af7Sopenharmony_ci "}\n"; 601e5c31af7Sopenharmony_ci} 602e5c31af7Sopenharmony_ci 603e5c31af7Sopenharmony_cideUint32 glc::subgroups::getSubgroupSize(Context& context) 604e5c31af7Sopenharmony_ci{ 605e5c31af7Sopenharmony_ci int subgroupSize = context.getDeqpContext().getContextInfo().getInt(GL_SUBGROUP_SIZE_KHR); 606e5c31af7Sopenharmony_ci 607e5c31af7Sopenharmony_ci return subgroupSize; 608e5c31af7Sopenharmony_ci} 609e5c31af7Sopenharmony_ci 610e5c31af7Sopenharmony_cideUint32 glc::subgroups::maxSupportedSubgroupSize() { 611e5c31af7Sopenharmony_ci return 128u; 612e5c31af7Sopenharmony_ci} 613e5c31af7Sopenharmony_ci 614e5c31af7Sopenharmony_cistd::string glc::subgroups::getShaderStageName(ShaderStageFlags stage) 615e5c31af7Sopenharmony_ci{ 616e5c31af7Sopenharmony_ci DE_ASSERT(stage & SHADER_STAGE_ALL_VALID); 617e5c31af7Sopenharmony_ci switch (stage) 618e5c31af7Sopenharmony_ci { 619e5c31af7Sopenharmony_ci default: 620e5c31af7Sopenharmony_ci DE_FATAL("Unhandled stage!"); 621e5c31af7Sopenharmony_ci return ""; 622e5c31af7Sopenharmony_ci case SHADER_STAGE_COMPUTE_BIT: 623e5c31af7Sopenharmony_ci return "compute"; 624e5c31af7Sopenharmony_ci case SHADER_STAGE_FRAGMENT_BIT: 625e5c31af7Sopenharmony_ci return "fragment"; 626e5c31af7Sopenharmony_ci case SHADER_STAGE_VERTEX_BIT: 627e5c31af7Sopenharmony_ci return "vertex"; 628e5c31af7Sopenharmony_ci case SHADER_STAGE_GEOMETRY_BIT: 629e5c31af7Sopenharmony_ci return "geometry"; 630e5c31af7Sopenharmony_ci case SHADER_STAGE_TESS_CONTROL_BIT: 631e5c31af7Sopenharmony_ci return "tess_control"; 632e5c31af7Sopenharmony_ci case SHADER_STAGE_TESS_EVALUATION_BIT: 633e5c31af7Sopenharmony_ci return "tess_eval"; 634e5c31af7Sopenharmony_ci } 635e5c31af7Sopenharmony_ci} 636e5c31af7Sopenharmony_ci 637e5c31af7Sopenharmony_cistd::string glc::subgroups::getSubgroupFeatureName(SubgroupFeatureFlags bit) 638e5c31af7Sopenharmony_ci{ 639e5c31af7Sopenharmony_ci DE_ASSERT(bit & SUBGROUP_FEATURE_ALL_VALID); 640e5c31af7Sopenharmony_ci switch (bit) 641e5c31af7Sopenharmony_ci { 642e5c31af7Sopenharmony_ci default: 643e5c31af7Sopenharmony_ci DE_FATAL("Unknown subgroup feature category!"); 644e5c31af7Sopenharmony_ci return ""; 645e5c31af7Sopenharmony_ci case SUBGROUP_FEATURE_BASIC_BIT: 646e5c31af7Sopenharmony_ci return "GL_SUBGROUP_FEATURE_BASIC_BIT_KHR"; 647e5c31af7Sopenharmony_ci case SUBGROUP_FEATURE_VOTE_BIT: 648e5c31af7Sopenharmony_ci return "GL_SUBGROUP_FEATURE_VOTE_BIT_KHR"; 649e5c31af7Sopenharmony_ci case SUBGROUP_FEATURE_ARITHMETIC_BIT: 650e5c31af7Sopenharmony_ci return "GL_SUBGROUP_FEATURE_ARITHMETIC_BIT_KHR"; 651e5c31af7Sopenharmony_ci case SUBGROUP_FEATURE_BALLOT_BIT: 652e5c31af7Sopenharmony_ci return "GL_SUBGROUP_FEATURE_BALLOT_BIT_KHR"; 653e5c31af7Sopenharmony_ci case SUBGROUP_FEATURE_SHUFFLE_BIT: 654e5c31af7Sopenharmony_ci return "GL_SUBGROUP_FEATURE_SHUFFLE_BIT_KHR"; 655e5c31af7Sopenharmony_ci case SUBGROUP_FEATURE_SHUFFLE_RELATIVE_BIT: 656e5c31af7Sopenharmony_ci return "GL_SUBGROUP_FEATURE_SHUFFLE_RELATIVE_BIT_KHR"; 657e5c31af7Sopenharmony_ci case SUBGROUP_FEATURE_CLUSTERED_BIT: 658e5c31af7Sopenharmony_ci return "GL_SUBGROUP_FEATURE_CLUSTERED_BIT_KHR"; 659e5c31af7Sopenharmony_ci case SUBGROUP_FEATURE_QUAD_BIT: 660e5c31af7Sopenharmony_ci return "GL_SUBGROUP_FEATURE_QUAD_BIT_KHR"; 661e5c31af7Sopenharmony_ci case SUBGROUP_FEATURE_PARTITIONED_BIT_NV: 662e5c31af7Sopenharmony_ci return "GL_SUBGROUP_FEATURE_PARTITIONED_BIT_NV"; 663e5c31af7Sopenharmony_ci } 664e5c31af7Sopenharmony_ci} 665e5c31af7Sopenharmony_ci 666e5c31af7Sopenharmony_civoid glc::subgroups::addNoSubgroupShader (SourceCollections& programCollection) 667e5c31af7Sopenharmony_ci{ 668e5c31af7Sopenharmony_ci { 669e5c31af7Sopenharmony_ci const std::string vertNoSubgroupGLSL = 670e5c31af7Sopenharmony_ci "${VERSION_DECL}\n" 671e5c31af7Sopenharmony_ci "void main (void)\n" 672e5c31af7Sopenharmony_ci "{\n" 673e5c31af7Sopenharmony_ci " float pixelSize = 2.0f/1024.0f;\n" 674e5c31af7Sopenharmony_ci " float pixelPosition = pixelSize/2.0f - 1.0f;\n" 675e5c31af7Sopenharmony_ci " gl_Position = vec4(float(gl_VertexID) * pixelSize + pixelPosition, 0.0f, 0.0f, 1.0f);\n" 676e5c31af7Sopenharmony_ci " gl_PointSize = 1.0f;\n" 677e5c31af7Sopenharmony_ci "}\n"; 678e5c31af7Sopenharmony_ci programCollection.add("vert_noSubgroup") << glu::VertexSource(vertNoSubgroupGLSL); 679e5c31af7Sopenharmony_ci } 680e5c31af7Sopenharmony_ci 681e5c31af7Sopenharmony_ci { 682e5c31af7Sopenharmony_ci const std::string tescNoSubgroupGLSL = 683e5c31af7Sopenharmony_ci "${VERSION_DECL}\n" 684e5c31af7Sopenharmony_ci "layout(vertices=1) out;\n" 685e5c31af7Sopenharmony_ci "\n" 686e5c31af7Sopenharmony_ci "void main (void)\n" 687e5c31af7Sopenharmony_ci "{\n" 688e5c31af7Sopenharmony_ci " if (gl_InvocationID == 0)\n" 689e5c31af7Sopenharmony_ci " {\n" 690e5c31af7Sopenharmony_ci " gl_TessLevelOuter[0] = 1.0f;\n" 691e5c31af7Sopenharmony_ci " gl_TessLevelOuter[1] = 1.0f;\n" 692e5c31af7Sopenharmony_ci " }\n" 693e5c31af7Sopenharmony_ci " gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n" 694e5c31af7Sopenharmony_ci "}\n"; 695e5c31af7Sopenharmony_ci programCollection.add("tesc_noSubgroup") << glu::TessellationControlSource(tescNoSubgroupGLSL); 696e5c31af7Sopenharmony_ci } 697e5c31af7Sopenharmony_ci 698e5c31af7Sopenharmony_ci { 699e5c31af7Sopenharmony_ci const std::string teseNoSubgroupGLSL = 700e5c31af7Sopenharmony_ci "${VERSION_DECL}\n" 701e5c31af7Sopenharmony_ci "layout(isolines) in;\n" 702e5c31af7Sopenharmony_ci "\n" 703e5c31af7Sopenharmony_ci "void main (void)\n" 704e5c31af7Sopenharmony_ci "{\n" 705e5c31af7Sopenharmony_ci " float pixelSize = 2.0f/1024.0f;\n" 706e5c31af7Sopenharmony_ci " gl_Position = gl_in[0].gl_Position + gl_TessCoord.x * pixelSize / 2.0f;\n" 707e5c31af7Sopenharmony_ci "}\n"; 708e5c31af7Sopenharmony_ci programCollection.add("tese_noSubgroup") << glu::TessellationEvaluationSource(teseNoSubgroupGLSL); 709e5c31af7Sopenharmony_ci } 710e5c31af7Sopenharmony_ci 711e5c31af7Sopenharmony_ci} 712e5c31af7Sopenharmony_ci 713e5c31af7Sopenharmony_cistd::string glc::subgroups::getVertShaderForStage(const ShaderStageFlags stage) 714e5c31af7Sopenharmony_ci{ 715e5c31af7Sopenharmony_ci DE_ASSERT(stage & SHADER_STAGE_ALL_VALID); 716e5c31af7Sopenharmony_ci switch (stage) 717e5c31af7Sopenharmony_ci { 718e5c31af7Sopenharmony_ci default: 719e5c31af7Sopenharmony_ci DE_FATAL("Unhandled stage!"); 720e5c31af7Sopenharmony_ci return ""; 721e5c31af7Sopenharmony_ci case SHADER_STAGE_FRAGMENT_BIT: 722e5c31af7Sopenharmony_ci return 723e5c31af7Sopenharmony_ci "${VERSION_DECL}\n" 724e5c31af7Sopenharmony_ci "void main (void)\n" 725e5c31af7Sopenharmony_ci "{\n" 726e5c31af7Sopenharmony_ci " float pixelSize = 2.0f/1024.0f;\n" 727e5c31af7Sopenharmony_ci " float pixelPosition = pixelSize/2.0f - 1.0f;\n" 728e5c31af7Sopenharmony_ci " gl_Position = vec4(float(gl_VertexID) * pixelSize + pixelPosition, 0.0f, 0.0f, 1.0f);\n" 729e5c31af7Sopenharmony_ci "}\n"; 730e5c31af7Sopenharmony_ci case SHADER_STAGE_GEOMETRY_BIT: 731e5c31af7Sopenharmony_ci return 732e5c31af7Sopenharmony_ci "${VERSION_DECL}\n" 733e5c31af7Sopenharmony_ci "void main (void)\n" 734e5c31af7Sopenharmony_ci "{\n" 735e5c31af7Sopenharmony_ci "}\n"; 736e5c31af7Sopenharmony_ci case SHADER_STAGE_TESS_CONTROL_BIT: 737e5c31af7Sopenharmony_ci case SHADER_STAGE_TESS_EVALUATION_BIT: 738e5c31af7Sopenharmony_ci return 739e5c31af7Sopenharmony_ci "${VERSION_DECL}\n" 740e5c31af7Sopenharmony_ci "void main (void)\n" 741e5c31af7Sopenharmony_ci "{\n" 742e5c31af7Sopenharmony_ci "}\n"; 743e5c31af7Sopenharmony_ci } 744e5c31af7Sopenharmony_ci} 745e5c31af7Sopenharmony_ci 746e5c31af7Sopenharmony_cibool glc::subgroups::isSubgroupSupported(Context& context) 747e5c31af7Sopenharmony_ci{ 748e5c31af7Sopenharmony_ci return context.getDeqpContext().getContextInfo().isExtensionSupported("GL_KHR_shader_subgroup"); 749e5c31af7Sopenharmony_ci} 750e5c31af7Sopenharmony_ci 751e5c31af7Sopenharmony_cibool glc::subgroups::areSubgroupOperationsSupportedForStage( 752e5c31af7Sopenharmony_ci Context& context, const ShaderStageFlags stage) 753e5c31af7Sopenharmony_ci{ 754e5c31af7Sopenharmony_ci DE_ASSERT(stage & SHADER_STAGE_ALL_VALID); 755e5c31af7Sopenharmony_ci int supportedStages = context.getDeqpContext().getContextInfo().getInt(GL_SUBGROUP_SUPPORTED_STAGES_KHR); 756e5c31af7Sopenharmony_ci 757e5c31af7Sopenharmony_ci return (stage & supportedStages) ? true : false; 758e5c31af7Sopenharmony_ci} 759e5c31af7Sopenharmony_ci 760e5c31af7Sopenharmony_cibool glc::subgroups::areSubgroupOperationsRequiredForStage( 761e5c31af7Sopenharmony_ci const ShaderStageFlags stage) 762e5c31af7Sopenharmony_ci{ 763e5c31af7Sopenharmony_ci DE_ASSERT(stage & SHADER_STAGE_ALL_VALID); 764e5c31af7Sopenharmony_ci switch (stage) 765e5c31af7Sopenharmony_ci { 766e5c31af7Sopenharmony_ci default: 767e5c31af7Sopenharmony_ci return false; 768e5c31af7Sopenharmony_ci case SHADER_STAGE_COMPUTE_BIT: 769e5c31af7Sopenharmony_ci return true; 770e5c31af7Sopenharmony_ci } 771e5c31af7Sopenharmony_ci} 772e5c31af7Sopenharmony_ci 773e5c31af7Sopenharmony_cibool glc::subgroups::isSubgroupFeatureSupportedForDevice( 774e5c31af7Sopenharmony_ci Context& context, 775e5c31af7Sopenharmony_ci const SubgroupFeatureFlags bit) 776e5c31af7Sopenharmony_ci{ 777e5c31af7Sopenharmony_ci DE_ASSERT(bit & SUBGROUP_FEATURE_ALL_VALID); 778e5c31af7Sopenharmony_ci 779e5c31af7Sopenharmony_ci int supportedOperations = context.getDeqpContext().getContextInfo().getInt(GL_SUBGROUP_SUPPORTED_FEATURES_KHR); 780e5c31af7Sopenharmony_ci 781e5c31af7Sopenharmony_ci return (bit & supportedOperations) ? true : false; 782e5c31af7Sopenharmony_ci} 783e5c31af7Sopenharmony_ci 784e5c31af7Sopenharmony_cibool glc::subgroups::isFragmentSSBOSupportedForDevice(Context& context) 785e5c31af7Sopenharmony_ci{ 786e5c31af7Sopenharmony_ci int numFragmentSSBOs = context.getDeqpContext().getContextInfo().getInt(GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS); 787e5c31af7Sopenharmony_ci 788e5c31af7Sopenharmony_ci return (numFragmentSSBOs > 0) ? true : false; 789e5c31af7Sopenharmony_ci} 790e5c31af7Sopenharmony_ci 791e5c31af7Sopenharmony_cibool glc::subgroups::isVertexSSBOSupportedForDevice(Context& context) 792e5c31af7Sopenharmony_ci{ 793e5c31af7Sopenharmony_ci int numVertexSSBOs = context.getDeqpContext().getContextInfo().getInt(GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS); 794e5c31af7Sopenharmony_ci 795e5c31af7Sopenharmony_ci return (numVertexSSBOs > 0) ? true : false; 796e5c31af7Sopenharmony_ci} 797e5c31af7Sopenharmony_ci 798e5c31af7Sopenharmony_cibool glc::subgroups::isImageSupportedForStageOnDevice(Context& context, const ShaderStageFlags stage) 799e5c31af7Sopenharmony_ci{ 800e5c31af7Sopenharmony_ci glw::GLint stageQuery; 801e5c31af7Sopenharmony_ci DE_ASSERT(stage & SHADER_STAGE_ALL_VALID); 802e5c31af7Sopenharmony_ci 803e5c31af7Sopenharmony_ci // image uniforms are optional in VTG stages 804e5c31af7Sopenharmony_ci switch (stage) 805e5c31af7Sopenharmony_ci { 806e5c31af7Sopenharmony_ci case SHADER_STAGE_FRAGMENT_BIT: 807e5c31af7Sopenharmony_ci case SHADER_STAGE_COMPUTE_BIT: 808e5c31af7Sopenharmony_ci default: 809e5c31af7Sopenharmony_ci return true; 810e5c31af7Sopenharmony_ci case SHADER_STAGE_VERTEX_BIT: 811e5c31af7Sopenharmony_ci stageQuery = GL_MAX_VERTEX_IMAGE_UNIFORMS; 812e5c31af7Sopenharmony_ci break; 813e5c31af7Sopenharmony_ci case SHADER_STAGE_TESS_CONTROL_BIT: 814e5c31af7Sopenharmony_ci stageQuery = GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS; 815e5c31af7Sopenharmony_ci break; 816e5c31af7Sopenharmony_ci case SHADER_STAGE_TESS_EVALUATION_BIT: 817e5c31af7Sopenharmony_ci stageQuery = GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS; 818e5c31af7Sopenharmony_ci break; 819e5c31af7Sopenharmony_ci case SHADER_STAGE_GEOMETRY_BIT: 820e5c31af7Sopenharmony_ci stageQuery = GL_MAX_GEOMETRY_IMAGE_UNIFORMS; 821e5c31af7Sopenharmony_ci break; 822e5c31af7Sopenharmony_ci } 823e5c31af7Sopenharmony_ci 824e5c31af7Sopenharmony_ci int numImages = context.getDeqpContext().getContextInfo().getInt(stageQuery); 825e5c31af7Sopenharmony_ci 826e5c31af7Sopenharmony_ci return (numImages > 0) ? true : false; 827e5c31af7Sopenharmony_ci} 828e5c31af7Sopenharmony_ci 829e5c31af7Sopenharmony_cibool glc::subgroups::isDoubleSupportedForDevice(Context& context) 830e5c31af7Sopenharmony_ci{ 831e5c31af7Sopenharmony_ci glu::ContextType contextType = context.getDeqpContext().getRenderContext().getType(); 832e5c31af7Sopenharmony_ci return (glu::contextSupports(contextType, glu::ApiType::core(4, 0)) || 833e5c31af7Sopenharmony_ci context.getDeqpContext().getContextInfo().isExtensionSupported("GL_ARB_gpu_shader_fp64")); 834e5c31af7Sopenharmony_ci} 835e5c31af7Sopenharmony_ci 836e5c31af7Sopenharmony_cibool glc::subgroups::isDoubleFormat(Format format) 837e5c31af7Sopenharmony_ci{ 838e5c31af7Sopenharmony_ci switch (format) 839e5c31af7Sopenharmony_ci { 840e5c31af7Sopenharmony_ci default: 841e5c31af7Sopenharmony_ci return false; 842e5c31af7Sopenharmony_ci case FORMAT_R64_SFLOAT: 843e5c31af7Sopenharmony_ci case FORMAT_R64G64_SFLOAT: 844e5c31af7Sopenharmony_ci case FORMAT_R64G64B64_SFLOAT: 845e5c31af7Sopenharmony_ci case FORMAT_R64G64B64A64_SFLOAT: 846e5c31af7Sopenharmony_ci return true; 847e5c31af7Sopenharmony_ci } 848e5c31af7Sopenharmony_ci} 849e5c31af7Sopenharmony_ci 850e5c31af7Sopenharmony_cistd::string glc::subgroups::getFormatNameForGLSL (Format format) 851e5c31af7Sopenharmony_ci{ 852e5c31af7Sopenharmony_ci switch (format) 853e5c31af7Sopenharmony_ci { 854e5c31af7Sopenharmony_ci default: 855e5c31af7Sopenharmony_ci DE_FATAL("Unhandled format!"); 856e5c31af7Sopenharmony_ci return ""; 857e5c31af7Sopenharmony_ci case FORMAT_R32_SINT: 858e5c31af7Sopenharmony_ci return "int"; 859e5c31af7Sopenharmony_ci case FORMAT_R32G32_SINT: 860e5c31af7Sopenharmony_ci return "ivec2"; 861e5c31af7Sopenharmony_ci case FORMAT_R32G32B32_SINT: 862e5c31af7Sopenharmony_ci return "ivec3"; 863e5c31af7Sopenharmony_ci case FORMAT_R32G32B32A32_SINT: 864e5c31af7Sopenharmony_ci return "ivec4"; 865e5c31af7Sopenharmony_ci case FORMAT_R32_UINT: 866e5c31af7Sopenharmony_ci return "uint"; 867e5c31af7Sopenharmony_ci case FORMAT_R32G32_UINT: 868e5c31af7Sopenharmony_ci return "uvec2"; 869e5c31af7Sopenharmony_ci case FORMAT_R32G32B32_UINT: 870e5c31af7Sopenharmony_ci return "uvec3"; 871e5c31af7Sopenharmony_ci case FORMAT_R32G32B32A32_UINT: 872e5c31af7Sopenharmony_ci return "uvec4"; 873e5c31af7Sopenharmony_ci case FORMAT_R32_SFLOAT: 874e5c31af7Sopenharmony_ci return "float"; 875e5c31af7Sopenharmony_ci case FORMAT_R32G32_SFLOAT: 876e5c31af7Sopenharmony_ci return "vec2"; 877e5c31af7Sopenharmony_ci case FORMAT_R32G32B32_SFLOAT: 878e5c31af7Sopenharmony_ci return "vec3"; 879e5c31af7Sopenharmony_ci case FORMAT_R32G32B32A32_SFLOAT: 880e5c31af7Sopenharmony_ci return "vec4"; 881e5c31af7Sopenharmony_ci case FORMAT_R64_SFLOAT: 882e5c31af7Sopenharmony_ci return "double"; 883e5c31af7Sopenharmony_ci case FORMAT_R64G64_SFLOAT: 884e5c31af7Sopenharmony_ci return "dvec2"; 885e5c31af7Sopenharmony_ci case FORMAT_R64G64B64_SFLOAT: 886e5c31af7Sopenharmony_ci return "dvec3"; 887e5c31af7Sopenharmony_ci case FORMAT_R64G64B64A64_SFLOAT: 888e5c31af7Sopenharmony_ci return "dvec4"; 889e5c31af7Sopenharmony_ci case FORMAT_R32_BOOL: 890e5c31af7Sopenharmony_ci return "bool"; 891e5c31af7Sopenharmony_ci case FORMAT_R32G32_BOOL: 892e5c31af7Sopenharmony_ci return "bvec2"; 893e5c31af7Sopenharmony_ci case FORMAT_R32G32B32_BOOL: 894e5c31af7Sopenharmony_ci return "bvec3"; 895e5c31af7Sopenharmony_ci case FORMAT_R32G32B32A32_BOOL: 896e5c31af7Sopenharmony_ci return "bvec4"; 897e5c31af7Sopenharmony_ci } 898e5c31af7Sopenharmony_ci} 899e5c31af7Sopenharmony_ci 900e5c31af7Sopenharmony_civoid glc::subgroups::setVertexShaderFrameBuffer (SourceCollections& programCollection) 901e5c31af7Sopenharmony_ci{ 902e5c31af7Sopenharmony_ci programCollection.add("vert") << glu::VertexSource( 903e5c31af7Sopenharmony_ci "${VERSION_DECL}\n" 904e5c31af7Sopenharmony_ci "layout(location = 0) in highp vec4 in_position;\n" 905e5c31af7Sopenharmony_ci "void main (void)\n" 906e5c31af7Sopenharmony_ci "{\n" 907e5c31af7Sopenharmony_ci " gl_Position = in_position;\n" 908e5c31af7Sopenharmony_ci "}\n"); 909e5c31af7Sopenharmony_ci} 910e5c31af7Sopenharmony_ci 911e5c31af7Sopenharmony_civoid glc::subgroups::setFragmentShaderFrameBuffer (SourceCollections& programCollection) 912e5c31af7Sopenharmony_ci{ 913e5c31af7Sopenharmony_ci programCollection.add("fragment") << glu::FragmentSource( 914e5c31af7Sopenharmony_ci "${VERSION_DECL}\n" 915e5c31af7Sopenharmony_ci "precision highp int;\n" 916e5c31af7Sopenharmony_ci "layout(location = 0) in highp float in_color;\n" 917e5c31af7Sopenharmony_ci "layout(location = 0) out uint out_color;\n" 918e5c31af7Sopenharmony_ci "void main()\n" 919e5c31af7Sopenharmony_ci "{\n" 920e5c31af7Sopenharmony_ci " out_color = uint(in_color);\n" 921e5c31af7Sopenharmony_ci "}\n"); 922e5c31af7Sopenharmony_ci} 923e5c31af7Sopenharmony_ci 924e5c31af7Sopenharmony_civoid glc::subgroups::setTesCtrlShaderFrameBuffer (SourceCollections& programCollection) 925e5c31af7Sopenharmony_ci{ 926e5c31af7Sopenharmony_ci programCollection.add("tesc") << glu::TessellationControlSource( 927e5c31af7Sopenharmony_ci "${VERSION_DECL}\n" 928e5c31af7Sopenharmony_ci "#extension GL_KHR_shader_subgroup_basic: enable\n" 929e5c31af7Sopenharmony_ci "${TESS_EXTENSION}\n" 930e5c31af7Sopenharmony_ci "layout(vertices = 2) out;\n" 931e5c31af7Sopenharmony_ci "void main (void)\n" 932e5c31af7Sopenharmony_ci "{\n" 933e5c31af7Sopenharmony_ci " if (gl_InvocationID == 0)\n" 934e5c31af7Sopenharmony_ci " {\n" 935e5c31af7Sopenharmony_ci " gl_TessLevelOuter[0] = 1.0f;\n" 936e5c31af7Sopenharmony_ci " gl_TessLevelOuter[1] = 1.0f;\n" 937e5c31af7Sopenharmony_ci " }\n" 938e5c31af7Sopenharmony_ci " gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n" 939e5c31af7Sopenharmony_ci "}\n"); 940e5c31af7Sopenharmony_ci} 941e5c31af7Sopenharmony_ci 942e5c31af7Sopenharmony_civoid glc::subgroups::setTesEvalShaderFrameBuffer (SourceCollections& programCollection) 943e5c31af7Sopenharmony_ci{ 944e5c31af7Sopenharmony_ci programCollection.add("tese") << glu::TessellationEvaluationSource( 945e5c31af7Sopenharmony_ci "${VERSION_DECL}\n" 946e5c31af7Sopenharmony_ci "#extension GL_KHR_shader_subgroup_ballot: enable\n" 947e5c31af7Sopenharmony_ci "${TESS_EXTENSION}\n" 948e5c31af7Sopenharmony_ci "layout(isolines, equal_spacing, ccw ) in;\n" 949e5c31af7Sopenharmony_ci "layout(location = 0) in float in_color[];\n" 950e5c31af7Sopenharmony_ci "layout(location = 0) out float out_color;\n" 951e5c31af7Sopenharmony_ci "\n" 952e5c31af7Sopenharmony_ci "void main (void)\n" 953e5c31af7Sopenharmony_ci "{\n" 954e5c31af7Sopenharmony_ci " gl_Position = mix(gl_in[0].gl_Position, gl_in[1].gl_Position, gl_TessCoord.x);\n" 955e5c31af7Sopenharmony_ci " out_color = in_color[0];\n" 956e5c31af7Sopenharmony_ci "}\n"); 957e5c31af7Sopenharmony_ci} 958e5c31af7Sopenharmony_ci 959e5c31af7Sopenharmony_civoid glc::subgroups::addGeometryShadersFromTemplate (const std::string& glslTemplate, SourceCollections& collection) 960e5c31af7Sopenharmony_ci{ 961e5c31af7Sopenharmony_ci tcu::StringTemplate geometryTemplate(glslTemplate); 962e5c31af7Sopenharmony_ci 963e5c31af7Sopenharmony_ci map<string, string> linesParams; 964e5c31af7Sopenharmony_ci linesParams.insert(pair<string, string>("TOPOLOGY", "lines")); 965e5c31af7Sopenharmony_ci 966e5c31af7Sopenharmony_ci map<string, string> pointsParams; 967e5c31af7Sopenharmony_ci pointsParams.insert(pair<string, string>("TOPOLOGY", "points")); 968e5c31af7Sopenharmony_ci 969e5c31af7Sopenharmony_ci collection.add("geometry_lines") << glu::GeometrySource("${VERSION_DECL}\n" + geometryTemplate.specialize(linesParams)); 970e5c31af7Sopenharmony_ci collection.add("geometry_points") << glu::GeometrySource("${VERSION_DECL}\n" + geometryTemplate.specialize(pointsParams)); 971e5c31af7Sopenharmony_ci} 972e5c31af7Sopenharmony_ci 973e5c31af7Sopenharmony_civoid initializeMemory(deqp::Context& context, glw::GLvoid *hostPtr, subgroups::SSBOData& data) 974e5c31af7Sopenharmony_ci{ 975e5c31af7Sopenharmony_ci using namespace subgroups; 976e5c31af7Sopenharmony_ci const Format format = data.format; 977e5c31af7Sopenharmony_ci const deUint64 size = data.numElements * 978e5c31af7Sopenharmony_ci (data.isImage ? getFormatSizeInBytes(format) : getElementSizeInBytes(format, data.layout)); 979e5c31af7Sopenharmony_ci if (subgroups::SSBOData::InitializeNonZero == data.initializeType) 980e5c31af7Sopenharmony_ci { 981e5c31af7Sopenharmony_ci de::Random rnd(context.getTestContext().getCommandLine().getBaseSeed()); 982e5c31af7Sopenharmony_ci switch (format) 983e5c31af7Sopenharmony_ci { 984e5c31af7Sopenharmony_ci default: 985e5c31af7Sopenharmony_ci DE_FATAL("Illegal buffer format"); 986e5c31af7Sopenharmony_ci break; 987e5c31af7Sopenharmony_ci case FORMAT_R32_BOOL: 988e5c31af7Sopenharmony_ci case FORMAT_R32G32_BOOL: 989e5c31af7Sopenharmony_ci case FORMAT_R32G32B32_BOOL: 990e5c31af7Sopenharmony_ci case FORMAT_R32G32B32A32_BOOL: 991e5c31af7Sopenharmony_ci { 992e5c31af7Sopenharmony_ci deUint32* ptr = reinterpret_cast<deUint32*>(hostPtr); 993e5c31af7Sopenharmony_ci 994e5c31af7Sopenharmony_ci for (deUint64 k = 0; k < (size / sizeof(deUint32)); k++) 995e5c31af7Sopenharmony_ci { 996e5c31af7Sopenharmony_ci deUint32 r = rnd.getUint32(); 997e5c31af7Sopenharmony_ci ptr[k] = (r & 1) ? r : 0; 998e5c31af7Sopenharmony_ci } 999e5c31af7Sopenharmony_ci } 1000e5c31af7Sopenharmony_ci break; 1001e5c31af7Sopenharmony_ci case FORMAT_R32_SINT: 1002e5c31af7Sopenharmony_ci case FORMAT_R32G32_SINT: 1003e5c31af7Sopenharmony_ci case FORMAT_R32G32B32_SINT: 1004e5c31af7Sopenharmony_ci case FORMAT_R32G32B32A32_SINT: 1005e5c31af7Sopenharmony_ci case FORMAT_R32_UINT: 1006e5c31af7Sopenharmony_ci case FORMAT_R32G32_UINT: 1007e5c31af7Sopenharmony_ci case FORMAT_R32G32B32_UINT: 1008e5c31af7Sopenharmony_ci case FORMAT_R32G32B32A32_UINT: 1009e5c31af7Sopenharmony_ci { 1010e5c31af7Sopenharmony_ci deUint32* ptr = reinterpret_cast<deUint32*>(hostPtr); 1011e5c31af7Sopenharmony_ci 1012e5c31af7Sopenharmony_ci for (deUint64 k = 0; k < (size / sizeof(deUint32)); k++) 1013e5c31af7Sopenharmony_ci { 1014e5c31af7Sopenharmony_ci ptr[k] = rnd.getUint32(); 1015e5c31af7Sopenharmony_ci } 1016e5c31af7Sopenharmony_ci } 1017e5c31af7Sopenharmony_ci break; 1018e5c31af7Sopenharmony_ci case FORMAT_R32_SFLOAT: 1019e5c31af7Sopenharmony_ci case FORMAT_R32G32_SFLOAT: 1020e5c31af7Sopenharmony_ci case FORMAT_R32G32B32_SFLOAT: 1021e5c31af7Sopenharmony_ci case FORMAT_R32G32B32A32_SFLOAT: 1022e5c31af7Sopenharmony_ci { 1023e5c31af7Sopenharmony_ci float* ptr = reinterpret_cast<float*>(hostPtr); 1024e5c31af7Sopenharmony_ci 1025e5c31af7Sopenharmony_ci for (deUint64 k = 0; k < (size / sizeof(float)); k++) 1026e5c31af7Sopenharmony_ci { 1027e5c31af7Sopenharmony_ci ptr[k] = rnd.getFloat(); 1028e5c31af7Sopenharmony_ci } 1029e5c31af7Sopenharmony_ci } 1030e5c31af7Sopenharmony_ci break; 1031e5c31af7Sopenharmony_ci case FORMAT_R64_SFLOAT: 1032e5c31af7Sopenharmony_ci case FORMAT_R64G64_SFLOAT: 1033e5c31af7Sopenharmony_ci case FORMAT_R64G64B64_SFLOAT: 1034e5c31af7Sopenharmony_ci case FORMAT_R64G64B64A64_SFLOAT: 1035e5c31af7Sopenharmony_ci { 1036e5c31af7Sopenharmony_ci double* ptr = reinterpret_cast<double*>(hostPtr); 1037e5c31af7Sopenharmony_ci 1038e5c31af7Sopenharmony_ci for (deUint64 k = 0; k < (size / sizeof(double)); k++) 1039e5c31af7Sopenharmony_ci { 1040e5c31af7Sopenharmony_ci ptr[k] = rnd.getDouble(); 1041e5c31af7Sopenharmony_ci } 1042e5c31af7Sopenharmony_ci } 1043e5c31af7Sopenharmony_ci break; 1044e5c31af7Sopenharmony_ci } 1045e5c31af7Sopenharmony_ci } 1046e5c31af7Sopenharmony_ci else if (subgroups::SSBOData::InitializeZero == data.initializeType) 1047e5c31af7Sopenharmony_ci { 1048e5c31af7Sopenharmony_ci deUint32* ptr = reinterpret_cast<deUint32*>(hostPtr); 1049e5c31af7Sopenharmony_ci 1050e5c31af7Sopenharmony_ci for (deUint64 k = 0; k < size / 4; k++) 1051e5c31af7Sopenharmony_ci { 1052e5c31af7Sopenharmony_ci ptr[k] = 0; 1053e5c31af7Sopenharmony_ci } 1054e5c31af7Sopenharmony_ci } 1055e5c31af7Sopenharmony_ci 1056e5c31af7Sopenharmony_ci if (subgroups::SSBOData::InitializeNone != data.initializeType) 1057e5c31af7Sopenharmony_ci { 1058e5c31af7Sopenharmony_ci // nothing to do for GL 1059e5c31af7Sopenharmony_ci } 1060e5c31af7Sopenharmony_ci} 1061e5c31af7Sopenharmony_ci 1062e5c31af7Sopenharmony_cideUint32 getResultBinding (const glc::subgroups::ShaderStageFlags shaderStage) 1063e5c31af7Sopenharmony_ci{ 1064e5c31af7Sopenharmony_ci using namespace glc::subgroups; 1065e5c31af7Sopenharmony_ci switch(shaderStage) 1066e5c31af7Sopenharmony_ci { 1067e5c31af7Sopenharmony_ci case SHADER_STAGE_VERTEX_BIT: 1068e5c31af7Sopenharmony_ci return 0u; 1069e5c31af7Sopenharmony_ci case SHADER_STAGE_TESS_CONTROL_BIT: 1070e5c31af7Sopenharmony_ci return 1u; 1071e5c31af7Sopenharmony_ci case SHADER_STAGE_TESS_EVALUATION_BIT: 1072e5c31af7Sopenharmony_ci return 2u; 1073e5c31af7Sopenharmony_ci case SHADER_STAGE_GEOMETRY_BIT: 1074e5c31af7Sopenharmony_ci return 3u; 1075e5c31af7Sopenharmony_ci default: 1076e5c31af7Sopenharmony_ci DE_ASSERT(0); 1077e5c31af7Sopenharmony_ci return -1; 1078e5c31af7Sopenharmony_ci } 1079e5c31af7Sopenharmony_ci DE_ASSERT(0); 1080e5c31af7Sopenharmony_ci return -1; 1081e5c31af7Sopenharmony_ci} 1082e5c31af7Sopenharmony_ci 1083e5c31af7Sopenharmony_citcu::TestStatus glc::subgroups::makeTessellationEvaluationFrameBufferTest( 1084e5c31af7Sopenharmony_ci Context& context, Format format, SSBOData* extraData, 1085e5c31af7Sopenharmony_ci deUint32 extraDataCount, 1086e5c31af7Sopenharmony_ci bool (*checkResult)(std::vector<const void*> datas, deUint32 width, deUint32 subgroupSize), 1087e5c31af7Sopenharmony_ci const ShaderStageFlags shaderStage) 1088e5c31af7Sopenharmony_ci{ 1089e5c31af7Sopenharmony_ci tcu::TestLog& log = context.getDeqpContext().getTestContext().getLog(); 1090e5c31af7Sopenharmony_ci const glw::Functions& gl = context.getDeqpContext().getRenderContext().getFunctions(); 1091e5c31af7Sopenharmony_ci 1092e5c31af7Sopenharmony_ci const deUint32 maxWidth = getMaxWidth(); 1093e5c31af7Sopenharmony_ci vector<de::SharedPtr<BufferOrImage> > inputBuffers (extraDataCount); 1094e5c31af7Sopenharmony_ci 1095e5c31af7Sopenharmony_ci const GlslSource& vshader = context.getSourceCollection().get("vert"); 1096e5c31af7Sopenharmony_ci const GlslSource& tcshader = context.getSourceCollection().get("tesc"); 1097e5c31af7Sopenharmony_ci const GlslSource& teshader = context.getSourceCollection().get("tese"); 1098e5c31af7Sopenharmony_ci const GlslSource& fshader = context.getSourceCollection().get("fragment"); 1099e5c31af7Sopenharmony_ci 1100e5c31af7Sopenharmony_ci for (deUint32 i = 0u; i < extraDataCount; i++) 1101e5c31af7Sopenharmony_ci { 1102e5c31af7Sopenharmony_ci if (extraData[i].isImage) 1103e5c31af7Sopenharmony_ci { 1104e5c31af7Sopenharmony_ci inputBuffers[i] = de::SharedPtr<BufferOrImage>(new Image(context, static_cast<deUint32>(extraData[i].numElements), 1u, extraData[i].format)); 1105e5c31af7Sopenharmony_ci // haven't implemented init for images yet 1106e5c31af7Sopenharmony_ci DE_ASSERT(extraData[i].initializeType == subgroups::SSBOData::InitializeNone); 1107e5c31af7Sopenharmony_ci } 1108e5c31af7Sopenharmony_ci else 1109e5c31af7Sopenharmony_ci { 1110e5c31af7Sopenharmony_ci deUint64 size = getElementSizeInBytes(extraData[i].format, extraData[i].layout) * extraData[i].numElements; 1111e5c31af7Sopenharmony_ci inputBuffers[i] = de::SharedPtr<BufferOrImage>(new Buffer(context, size, GL_UNIFORM_BUFFER)); 1112e5c31af7Sopenharmony_ci 1113e5c31af7Sopenharmony_ci glw::GLvoid *ptr = inputBuffers[i]->getAsBuffer()->mapBufferPtr(); 1114e5c31af7Sopenharmony_ci initializeMemory(context.getDeqpContext(), ptr, extraData[i]); 1115e5c31af7Sopenharmony_ci inputBuffers[i]->getAsBuffer()->unmapBufferPtr(); 1116e5c31af7Sopenharmony_ci } 1117e5c31af7Sopenharmony_ci } 1118e5c31af7Sopenharmony_ci 1119e5c31af7Sopenharmony_ci for (deUint32 ndx = 0u; ndx < extraDataCount; ndx++) 1120e5c31af7Sopenharmony_ci { 1121e5c31af7Sopenharmony_ci log << tcu::TestLog::Message 1122e5c31af7Sopenharmony_ci << "binding inputBuffers[" << ndx << "](" << inputBuffers[ndx]->getType() << ", " << inputBuffers[ndx]->getId() << " ), " 1123e5c31af7Sopenharmony_ci << "stage = " << shaderStage << " , binding = " << extraData[ndx].binding << "\n" 1124e5c31af7Sopenharmony_ci << tcu::TestLog::EndMessage; 1125e5c31af7Sopenharmony_ci 1126e5c31af7Sopenharmony_ci if (inputBuffers[ndx]->isImage()) 1127e5c31af7Sopenharmony_ci { 1128e5c31af7Sopenharmony_ci gl.bindImageTexture(extraData[ndx].binding, inputBuffers[ndx]->getId(), 1129e5c31af7Sopenharmony_ci 0, GL_FALSE, 0, GL_READ_ONLY, extraData[ndx].format); 1130e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glBindImageTexture()"); 1131e5c31af7Sopenharmony_ci } else 1132e5c31af7Sopenharmony_ci { 1133e5c31af7Sopenharmony_ci gl.bindBufferBase(inputBuffers[ndx]->getType(), extraData[ndx].binding, inputBuffers[ndx]->getId()); 1134e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase()"); 1135e5c31af7Sopenharmony_ci } 1136e5c31af7Sopenharmony_ci } 1137e5c31af7Sopenharmony_ci 1138e5c31af7Sopenharmony_ci de::MovePtr<glu::ShaderProgram> pipeline( 1139e5c31af7Sopenharmony_ci makeGraphicsPipeline(context, (ShaderStageFlags)(SHADER_STAGE_VERTEX_BIT | SHADER_STAGE_FRAGMENT_BIT | SHADER_STAGE_TESS_CONTROL_BIT | SHADER_STAGE_TESS_EVALUATION_BIT), 1140e5c31af7Sopenharmony_ci &vshader, &fshader, DE_NULL, &tcshader, &teshader)); 1141e5c31af7Sopenharmony_ci if (!pipeline->isOk()) 1142e5c31af7Sopenharmony_ci { 1143e5c31af7Sopenharmony_ci return tcu::TestStatus::fail("tese graphics program build failed"); 1144e5c31af7Sopenharmony_ci } 1145e5c31af7Sopenharmony_ci 1146e5c31af7Sopenharmony_ci const deUint32 subgroupSize = getSubgroupSize(context); 1147e5c31af7Sopenharmony_ci const deUint64 vertexBufferSize = 2ull * maxWidth * sizeof(tcu::Vec4); 1148e5c31af7Sopenharmony_ci Buffer vertexBuffer (context, vertexBufferSize, GL_ARRAY_BUFFER); 1149e5c31af7Sopenharmony_ci unsigned totalIterations = 0u; 1150e5c31af7Sopenharmony_ci unsigned failedIterations = 0u; 1151e5c31af7Sopenharmony_ci Image discardableImage (context, maxWidth, 1u, format); 1152e5c31af7Sopenharmony_ci 1153e5c31af7Sopenharmony_ci { 1154e5c31af7Sopenharmony_ci glw::GLvoid * bufferPtr = vertexBuffer.mapBufferPtr(); 1155e5c31af7Sopenharmony_ci std::vector<tcu::Vec4> data (2u * maxWidth, tcu::Vec4(1.0f, 0.0f, 1.0f, 1.0f)); 1156e5c31af7Sopenharmony_ci const float pixelSize = 2.0f / static_cast<float>(maxWidth); 1157e5c31af7Sopenharmony_ci float leftHandPosition = -1.0f; 1158e5c31af7Sopenharmony_ci 1159e5c31af7Sopenharmony_ci for(deUint32 ndx = 0u; ndx < data.size(); ndx+=2u) 1160e5c31af7Sopenharmony_ci { 1161e5c31af7Sopenharmony_ci data[ndx][0] = leftHandPosition; 1162e5c31af7Sopenharmony_ci leftHandPosition += pixelSize; 1163e5c31af7Sopenharmony_ci data[ndx+1][0] = leftHandPosition; 1164e5c31af7Sopenharmony_ci } 1165e5c31af7Sopenharmony_ci 1166e5c31af7Sopenharmony_ci deMemcpy(bufferPtr, &data[0], data.size() * sizeof(tcu::Vec4)); 1167e5c31af7Sopenharmony_ci vertexBuffer.unmapBufferPtr(); 1168e5c31af7Sopenharmony_ci } 1169e5c31af7Sopenharmony_ci 1170e5c31af7Sopenharmony_ci Vao vao(context); 1171e5c31af7Sopenharmony_ci Fbo fbo(context); 1172e5c31af7Sopenharmony_ci fbo.bind2D(discardableImage); 1173e5c31af7Sopenharmony_ci 1174e5c31af7Sopenharmony_ci gl.viewport(0, 0, maxWidth, 1u); 1175e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport"); 1176e5c31af7Sopenharmony_ci 1177e5c31af7Sopenharmony_ci const deUint64 imageResultSize = getFormatSizeInBytes(format) * maxWidth; 1178e5c31af7Sopenharmony_ci vector<glw::GLubyte> imageBufferResult(imageResultSize); 1179e5c31af7Sopenharmony_ci const deUint64 vertexBufferOffset = 0u; 1180e5c31af7Sopenharmony_ci 1181e5c31af7Sopenharmony_ci for (deUint32 width = 1u; width < maxWidth; width = getNextWidth(width)) 1182e5c31af7Sopenharmony_ci { 1183e5c31af7Sopenharmony_ci totalIterations++; 1184e5c31af7Sopenharmony_ci 1185e5c31af7Sopenharmony_ci { 1186e5c31af7Sopenharmony_ci gl.clearColor(0.0f, 0.0f, 0.0f, 0.0f); 1187e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glClearColor"); 1188e5c31af7Sopenharmony_ci gl.clear(GL_COLOR_BUFFER_BIT); 1189e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glClear"); 1190e5c31af7Sopenharmony_ci 1191e5c31af7Sopenharmony_ci gl.useProgram(pipeline->getProgram()); 1192e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram"); 1193e5c31af7Sopenharmony_ci 1194e5c31af7Sopenharmony_ci gl.enableVertexAttribArray(0); 1195e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray"); 1196e5c31af7Sopenharmony_ci 1197e5c31af7Sopenharmony_ci gl.bindBuffer(GL_ARRAY_BUFFER, vertexBuffer.getId()); 1198e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer"); 1199e5c31af7Sopenharmony_ci 1200e5c31af7Sopenharmony_ci gl.vertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(tcu::Vec4), glu::BufferOffsetAsPointer(vertexBufferOffset)); 1201e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer"); 1202e5c31af7Sopenharmony_ci 1203e5c31af7Sopenharmony_ci gl.patchParameteri(GL_PATCH_VERTICES, 2u); 1204e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glPatchParameter(PATCH_VERTICES)"); 1205e5c31af7Sopenharmony_ci 1206e5c31af7Sopenharmony_ci gl.drawArrays(GL_PATCHES, 0, 2 * width); 1207e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays"); 1208e5c31af7Sopenharmony_ci 1209e5c31af7Sopenharmony_ci gl.disableVertexAttribArray(0); 1210e5c31af7Sopenharmony_ci 1211e5c31af7Sopenharmony_ci GLenum readFormat; 1212e5c31af7Sopenharmony_ci GLenum readType; 1213e5c31af7Sopenharmony_ci getFormatReadInfo(format, readFormat, readType); 1214e5c31af7Sopenharmony_ci 1215e5c31af7Sopenharmony_ci gl.readPixels(0, 0, width, 1, readFormat, readType, (GLvoid*)&imageBufferResult[0]); 1216e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels"); 1217e5c31af7Sopenharmony_ci } 1218e5c31af7Sopenharmony_ci 1219e5c31af7Sopenharmony_ci { 1220e5c31af7Sopenharmony_ci std::vector<const void*> datas; 1221e5c31af7Sopenharmony_ci datas.push_back(&imageBufferResult[0]); 1222e5c31af7Sopenharmony_ci if (!checkResult(datas, width/2u, subgroupSize)) 1223e5c31af7Sopenharmony_ci failedIterations++; 1224e5c31af7Sopenharmony_ci } 1225e5c31af7Sopenharmony_ci } 1226e5c31af7Sopenharmony_ci 1227e5c31af7Sopenharmony_ci if (0 < failedIterations) 1228e5c31af7Sopenharmony_ci { 1229e5c31af7Sopenharmony_ci log << tcu::TestLog::Message << (totalIterations - failedIterations) << " / " 1230e5c31af7Sopenharmony_ci << totalIterations << " values passed" << tcu::TestLog::EndMessage; 1231e5c31af7Sopenharmony_ci return tcu::TestStatus::fail("Failed!"); 1232e5c31af7Sopenharmony_ci } else 1233e5c31af7Sopenharmony_ci { 1234e5c31af7Sopenharmony_ci log << tcu::TestLog::Message << (totalIterations - failedIterations) << " / " 1235e5c31af7Sopenharmony_ci <<totalIterations << " values passed" << tcu::TestLog::EndMessage; 1236e5c31af7Sopenharmony_ci } 1237e5c31af7Sopenharmony_ci 1238e5c31af7Sopenharmony_ci return tcu::TestStatus::pass("OK"); 1239e5c31af7Sopenharmony_ci} 1240e5c31af7Sopenharmony_ci 1241e5c31af7Sopenharmony_cibool glc::subgroups::check(std::vector<const void*> datas, 1242e5c31af7Sopenharmony_ci deUint32 width, deUint32 ref) 1243e5c31af7Sopenharmony_ci{ 1244e5c31af7Sopenharmony_ci const deUint32* data = reinterpret_cast<const deUint32*>(datas[0]); 1245e5c31af7Sopenharmony_ci 1246e5c31af7Sopenharmony_ci for (deUint32 n = 0; n < width; ++n) 1247e5c31af7Sopenharmony_ci { 1248e5c31af7Sopenharmony_ci if (data[n] != ref) 1249e5c31af7Sopenharmony_ci { 1250e5c31af7Sopenharmony_ci return false; 1251e5c31af7Sopenharmony_ci } 1252e5c31af7Sopenharmony_ci } 1253e5c31af7Sopenharmony_ci 1254e5c31af7Sopenharmony_ci return true; 1255e5c31af7Sopenharmony_ci} 1256e5c31af7Sopenharmony_ci 1257e5c31af7Sopenharmony_cibool glc::subgroups::checkCompute(std::vector<const void*> datas, 1258e5c31af7Sopenharmony_ci const deUint32 numWorkgroups[3], const deUint32 localSize[3], 1259e5c31af7Sopenharmony_ci deUint32 ref) 1260e5c31af7Sopenharmony_ci{ 1261e5c31af7Sopenharmony_ci const deUint32 globalSizeX = numWorkgroups[0] * localSize[0]; 1262e5c31af7Sopenharmony_ci const deUint32 globalSizeY = numWorkgroups[1] * localSize[1]; 1263e5c31af7Sopenharmony_ci const deUint32 globalSizeZ = numWorkgroups[2] * localSize[2]; 1264e5c31af7Sopenharmony_ci 1265e5c31af7Sopenharmony_ci return check(datas, globalSizeX * globalSizeY * globalSizeZ, ref); 1266e5c31af7Sopenharmony_ci} 1267e5c31af7Sopenharmony_ci 1268e5c31af7Sopenharmony_ci 1269e5c31af7Sopenharmony_citcu::TestStatus glc::subgroups::makeGeometryFrameBufferTest( 1270e5c31af7Sopenharmony_ci Context& context, Format format, SSBOData* extraData, 1271e5c31af7Sopenharmony_ci deUint32 extraDataCount, 1272e5c31af7Sopenharmony_ci bool (*checkResult)(std::vector<const void*> datas, deUint32 width, deUint32 subgroupSize)) 1273e5c31af7Sopenharmony_ci{ 1274e5c31af7Sopenharmony_ci tcu::TestLog& log = context.getDeqpContext().getTestContext().getLog(); 1275e5c31af7Sopenharmony_ci const glw::Functions& gl = context.getDeqpContext().getRenderContext().getFunctions(); 1276e5c31af7Sopenharmony_ci 1277e5c31af7Sopenharmony_ci const deUint32 maxWidth = getMaxWidth(); 1278e5c31af7Sopenharmony_ci vector<de::SharedPtr<BufferOrImage> > inputBuffers (extraDataCount); 1279e5c31af7Sopenharmony_ci 1280e5c31af7Sopenharmony_ci const GlslSource& vshader = context.getSourceCollection().get("vert"); 1281e5c31af7Sopenharmony_ci const GlslSource& gshader = context.getSourceCollection().get("geometry"); 1282e5c31af7Sopenharmony_ci const GlslSource& fshader = context.getSourceCollection().get("fragment"); 1283e5c31af7Sopenharmony_ci 1284e5c31af7Sopenharmony_ci for (deUint32 i = 0u; i < extraDataCount; i++) 1285e5c31af7Sopenharmony_ci { 1286e5c31af7Sopenharmony_ci if (extraData[i].isImage) 1287e5c31af7Sopenharmony_ci { 1288e5c31af7Sopenharmony_ci inputBuffers[i] = de::SharedPtr<BufferOrImage>(new Image(context, static_cast<deUint32>(extraData[i].numElements), 1u, extraData[i].format)); 1289e5c31af7Sopenharmony_ci // haven't implemented init for images yet 1290e5c31af7Sopenharmony_ci DE_ASSERT(extraData[i].initializeType == subgroups::SSBOData::InitializeNone); 1291e5c31af7Sopenharmony_ci } 1292e5c31af7Sopenharmony_ci else 1293e5c31af7Sopenharmony_ci { 1294e5c31af7Sopenharmony_ci deUint64 size = getElementSizeInBytes(extraData[i].format, extraData[i].layout) * extraData[i].numElements; 1295e5c31af7Sopenharmony_ci inputBuffers[i] = de::SharedPtr<BufferOrImage>(new Buffer(context, size, GL_UNIFORM_BUFFER)); 1296e5c31af7Sopenharmony_ci 1297e5c31af7Sopenharmony_ci glw::GLvoid *ptr = inputBuffers[i]->getAsBuffer()->mapBufferPtr(); 1298e5c31af7Sopenharmony_ci initializeMemory(context.getDeqpContext(), ptr, extraData[i]); 1299e5c31af7Sopenharmony_ci inputBuffers[i]->getAsBuffer()->unmapBufferPtr(); 1300e5c31af7Sopenharmony_ci } 1301e5c31af7Sopenharmony_ci } 1302e5c31af7Sopenharmony_ci 1303e5c31af7Sopenharmony_ci for (deUint32 ndx = 0u; ndx < extraDataCount; ndx++) 1304e5c31af7Sopenharmony_ci { 1305e5c31af7Sopenharmony_ci log << tcu::TestLog::Message 1306e5c31af7Sopenharmony_ci << "binding inputBuffers[" << ndx << "](" << inputBuffers[ndx]->getType() << ", " << inputBuffers[ndx]->getId() << " ), " 1307e5c31af7Sopenharmony_ci << "GEOMETRY, binding = " << extraData[ndx].binding << "\n" 1308e5c31af7Sopenharmony_ci << tcu::TestLog::EndMessage; 1309e5c31af7Sopenharmony_ci 1310e5c31af7Sopenharmony_ci if (inputBuffers[ndx]->isImage()) 1311e5c31af7Sopenharmony_ci { 1312e5c31af7Sopenharmony_ci gl.bindImageTexture(extraData[ndx].binding, inputBuffers[ndx]->getId(), 1313e5c31af7Sopenharmony_ci 0, GL_FALSE, 0, GL_READ_ONLY, extraData[ndx].format); 1314e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glBindImageTexture()"); 1315e5c31af7Sopenharmony_ci } else 1316e5c31af7Sopenharmony_ci { 1317e5c31af7Sopenharmony_ci gl.bindBufferBase(inputBuffers[ndx]->getType(), extraData[ndx].binding, inputBuffers[ndx]->getId()); 1318e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase()"); 1319e5c31af7Sopenharmony_ci } 1320e5c31af7Sopenharmony_ci } 1321e5c31af7Sopenharmony_ci 1322e5c31af7Sopenharmony_ci de::MovePtr<glu::ShaderProgram> pipeline( 1323e5c31af7Sopenharmony_ci makeGraphicsPipeline(context, (ShaderStageFlags)(SHADER_STAGE_VERTEX_BIT | SHADER_STAGE_FRAGMENT_BIT | SHADER_STAGE_GEOMETRY_BIT), 1324e5c31af7Sopenharmony_ci &vshader, &fshader, &gshader, DE_NULL, DE_NULL)); 1325e5c31af7Sopenharmony_ci if (!pipeline->isOk()) 1326e5c31af7Sopenharmony_ci { 1327e5c31af7Sopenharmony_ci return tcu::TestStatus::fail("geom graphics program build failed"); 1328e5c31af7Sopenharmony_ci } 1329e5c31af7Sopenharmony_ci 1330e5c31af7Sopenharmony_ci const deUint32 subgroupSize = getSubgroupSize(context); 1331e5c31af7Sopenharmony_ci const deUint64 vertexBufferSize = maxWidth * sizeof(tcu::Vec4); 1332e5c31af7Sopenharmony_ci Buffer vertexBuffer (context, vertexBufferSize, GL_ARRAY_BUFFER); 1333e5c31af7Sopenharmony_ci unsigned totalIterations = 0u; 1334e5c31af7Sopenharmony_ci unsigned failedIterations = 0u; 1335e5c31af7Sopenharmony_ci Image discardableImage (context, maxWidth, 1u, format); 1336e5c31af7Sopenharmony_ci 1337e5c31af7Sopenharmony_ci { 1338e5c31af7Sopenharmony_ci glw::GLvoid * bufferPtr = vertexBuffer.mapBufferPtr(); 1339e5c31af7Sopenharmony_ci std::vector<tcu::Vec4> data (maxWidth, tcu::Vec4(1.0f, 0.5f, 1.0f, 1.0f)); 1340e5c31af7Sopenharmony_ci const float pixelSize = 2.0f / static_cast<float>(maxWidth); 1341e5c31af7Sopenharmony_ci float leftHandPosition = -1.0f; 1342e5c31af7Sopenharmony_ci 1343e5c31af7Sopenharmony_ci for(deUint32 ndx = 0u; ndx < maxWidth; ++ndx) 1344e5c31af7Sopenharmony_ci { 1345e5c31af7Sopenharmony_ci data[ndx][0] = leftHandPosition + pixelSize / 2.0f; 1346e5c31af7Sopenharmony_ci leftHandPosition += pixelSize; 1347e5c31af7Sopenharmony_ci } 1348e5c31af7Sopenharmony_ci 1349e5c31af7Sopenharmony_ci deMemcpy(bufferPtr, &data[0], maxWidth * sizeof(tcu::Vec4)); 1350e5c31af7Sopenharmony_ci vertexBuffer.unmapBufferPtr(); 1351e5c31af7Sopenharmony_ci } 1352e5c31af7Sopenharmony_ci 1353e5c31af7Sopenharmony_ci Vao vao(context); 1354e5c31af7Sopenharmony_ci Fbo fbo(context); 1355e5c31af7Sopenharmony_ci fbo.bind2D(discardableImage); 1356e5c31af7Sopenharmony_ci 1357e5c31af7Sopenharmony_ci gl.viewport(0, 0, maxWidth, 1u); 1358e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport"); 1359e5c31af7Sopenharmony_ci 1360e5c31af7Sopenharmony_ci const deUint64 imageResultSize = getFormatSizeInBytes(format) * maxWidth; 1361e5c31af7Sopenharmony_ci vector<glw::GLubyte> imageBufferResult(imageResultSize); 1362e5c31af7Sopenharmony_ci const deUint64 vertexBufferOffset = 0u; 1363e5c31af7Sopenharmony_ci 1364e5c31af7Sopenharmony_ci for (deUint32 width = 1u; width < maxWidth; width = getNextWidth(width)) 1365e5c31af7Sopenharmony_ci { 1366e5c31af7Sopenharmony_ci totalIterations++; 1367e5c31af7Sopenharmony_ci 1368e5c31af7Sopenharmony_ci for (deUint32 ndx = 0u; ndx < inputBuffers.size(); ndx++) 1369e5c31af7Sopenharmony_ci { 1370e5c31af7Sopenharmony_ci if (inputBuffers[ndx]->isImage()) 1371e5c31af7Sopenharmony_ci { 1372e5c31af7Sopenharmony_ci DE_ASSERT(extraData[ndx].initializeType == subgroups::SSBOData::InitializeNone); 1373e5c31af7Sopenharmony_ci } else 1374e5c31af7Sopenharmony_ci { 1375e5c31af7Sopenharmony_ci glw::GLvoid *ptr = inputBuffers[ndx]->getAsBuffer()->mapBufferPtr(); 1376e5c31af7Sopenharmony_ci initializeMemory(context.getDeqpContext(), ptr, extraData[ndx]); 1377e5c31af7Sopenharmony_ci inputBuffers[ndx]->getAsBuffer()->unmapBufferPtr(); 1378e5c31af7Sopenharmony_ci } 1379e5c31af7Sopenharmony_ci } 1380e5c31af7Sopenharmony_ci 1381e5c31af7Sopenharmony_ci { 1382e5c31af7Sopenharmony_ci gl.clearColor(0.0f, 0.0f, 0.0f, 0.0f); 1383e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glClearColor"); 1384e5c31af7Sopenharmony_ci gl.clear(GL_COLOR_BUFFER_BIT); 1385e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glClear"); 1386e5c31af7Sopenharmony_ci 1387e5c31af7Sopenharmony_ci gl.useProgram(pipeline->getProgram()); 1388e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram"); 1389e5c31af7Sopenharmony_ci 1390e5c31af7Sopenharmony_ci gl.enableVertexAttribArray(0); 1391e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray"); 1392e5c31af7Sopenharmony_ci 1393e5c31af7Sopenharmony_ci gl.bindBuffer(GL_ARRAY_BUFFER, vertexBuffer.getId()); 1394e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer"); 1395e5c31af7Sopenharmony_ci 1396e5c31af7Sopenharmony_ci gl.vertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(tcu::Vec4), glu::BufferOffsetAsPointer(vertexBufferOffset)); 1397e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer"); 1398e5c31af7Sopenharmony_ci 1399e5c31af7Sopenharmony_ci gl.drawArrays(GL_POINTS, 0, width); 1400e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays"); 1401e5c31af7Sopenharmony_ci 1402e5c31af7Sopenharmony_ci gl.disableVertexAttribArray(0); 1403e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glDisableVertexAttribArray"); 1404e5c31af7Sopenharmony_ci 1405e5c31af7Sopenharmony_ci GLenum readFormat; 1406e5c31af7Sopenharmony_ci GLenum readType; 1407e5c31af7Sopenharmony_ci getFormatReadInfo(format, readFormat, readType); 1408e5c31af7Sopenharmony_ci 1409e5c31af7Sopenharmony_ci gl.readPixels(0, 0, width, 1, readFormat, readType, (GLvoid*)&imageBufferResult[0]); 1410e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels"); 1411e5c31af7Sopenharmony_ci } 1412e5c31af7Sopenharmony_ci 1413e5c31af7Sopenharmony_ci { 1414e5c31af7Sopenharmony_ci std::vector<const void*> datas; 1415e5c31af7Sopenharmony_ci datas.push_back(&imageBufferResult[0]); 1416e5c31af7Sopenharmony_ci if (!checkResult(datas, width, subgroupSize)) 1417e5c31af7Sopenharmony_ci failedIterations++; 1418e5c31af7Sopenharmony_ci } 1419e5c31af7Sopenharmony_ci } 1420e5c31af7Sopenharmony_ci 1421e5c31af7Sopenharmony_ci if (0 < failedIterations) 1422e5c31af7Sopenharmony_ci { 1423e5c31af7Sopenharmony_ci log << tcu::TestLog::Message << (totalIterations - failedIterations) << " / " 1424e5c31af7Sopenharmony_ci << totalIterations << " values passed" << tcu::TestLog::EndMessage; 1425e5c31af7Sopenharmony_ci return tcu::TestStatus::fail("Failed!"); 1426e5c31af7Sopenharmony_ci } else 1427e5c31af7Sopenharmony_ci { 1428e5c31af7Sopenharmony_ci log << tcu::TestLog::Message << (totalIterations - failedIterations) << " / " 1429e5c31af7Sopenharmony_ci <<totalIterations << " values passed" << tcu::TestLog::EndMessage; 1430e5c31af7Sopenharmony_ci } 1431e5c31af7Sopenharmony_ci 1432e5c31af7Sopenharmony_ci return tcu::TestStatus::pass("OK"); 1433e5c31af7Sopenharmony_ci} 1434e5c31af7Sopenharmony_ci 1435e5c31af7Sopenharmony_citcu::TestStatus glc::subgroups::allStages( 1436e5c31af7Sopenharmony_ci Context& context, Format format, SSBOData* extraDatas, 1437e5c31af7Sopenharmony_ci deUint32 extraDatasCount, 1438e5c31af7Sopenharmony_ci bool (*checkResult)(std::vector<const void*> datas, deUint32 width, deUint32 subgroupSize), 1439e5c31af7Sopenharmony_ci const ShaderStageFlags shaderStageTested) 1440e5c31af7Sopenharmony_ci{ 1441e5c31af7Sopenharmony_ci const deUint32 maxWidth = getMaxWidth(); 1442e5c31af7Sopenharmony_ci vector<ShaderStageFlags> stagesVector; 1443e5c31af7Sopenharmony_ci ShaderStageFlags shaderStageRequired = (ShaderStageFlags)0ull; 1444e5c31af7Sopenharmony_ci tcu::TestLog& log = context.getDeqpContext().getTestContext().getLog(); 1445e5c31af7Sopenharmony_ci const glw::Functions& gl = context.getDeqpContext().getRenderContext().getFunctions(); 1446e5c31af7Sopenharmony_ci 1447e5c31af7Sopenharmony_ci if (shaderStageTested & SHADER_STAGE_VERTEX_BIT) 1448e5c31af7Sopenharmony_ci { 1449e5c31af7Sopenharmony_ci stagesVector.push_back(SHADER_STAGE_VERTEX_BIT); 1450e5c31af7Sopenharmony_ci } 1451e5c31af7Sopenharmony_ci if (shaderStageTested & SHADER_STAGE_TESS_CONTROL_BIT) 1452e5c31af7Sopenharmony_ci { 1453e5c31af7Sopenharmony_ci stagesVector.push_back(SHADER_STAGE_TESS_CONTROL_BIT); 1454e5c31af7Sopenharmony_ci shaderStageRequired = (ShaderStageFlags)((deUint32)shaderStageRequired | ((deUint32)(shaderStageTested & SHADER_STAGE_TESS_EVALUATION_BIT) ? 0u : (deUint32)SHADER_STAGE_TESS_EVALUATION_BIT)); 1455e5c31af7Sopenharmony_ci shaderStageRequired = (ShaderStageFlags)((deUint32)shaderStageRequired | ((deUint32)(shaderStageTested & SHADER_STAGE_VERTEX_BIT) ? 0u : (deUint32)SHADER_STAGE_VERTEX_BIT)); 1456e5c31af7Sopenharmony_ci } 1457e5c31af7Sopenharmony_ci if (shaderStageTested & SHADER_STAGE_TESS_EVALUATION_BIT) 1458e5c31af7Sopenharmony_ci { 1459e5c31af7Sopenharmony_ci stagesVector.push_back(SHADER_STAGE_TESS_EVALUATION_BIT); 1460e5c31af7Sopenharmony_ci shaderStageRequired = (ShaderStageFlags)((deUint32)shaderStageRequired | ((deUint32)(shaderStageTested & SHADER_STAGE_VERTEX_BIT) ? 0u : (deUint32)SHADER_STAGE_VERTEX_BIT)); 1461e5c31af7Sopenharmony_ci shaderStageRequired = (ShaderStageFlags)((deUint32)shaderStageRequired | ((deUint32)(shaderStageTested & SHADER_STAGE_TESS_CONTROL_BIT) ? 0u : (deUint32)SHADER_STAGE_TESS_CONTROL_BIT)); 1462e5c31af7Sopenharmony_ci } 1463e5c31af7Sopenharmony_ci if (shaderStageTested & SHADER_STAGE_GEOMETRY_BIT) 1464e5c31af7Sopenharmony_ci { 1465e5c31af7Sopenharmony_ci stagesVector.push_back(SHADER_STAGE_GEOMETRY_BIT); 1466e5c31af7Sopenharmony_ci const ShaderStageFlags required = SHADER_STAGE_VERTEX_BIT; 1467e5c31af7Sopenharmony_ci shaderStageRequired = (ShaderStageFlags)((deUint32)shaderStageRequired | ((deUint32)(shaderStageTested & required) ? 0u : (deUint32)required)); 1468e5c31af7Sopenharmony_ci } 1469e5c31af7Sopenharmony_ci if (shaderStageTested & SHADER_STAGE_FRAGMENT_BIT) 1470e5c31af7Sopenharmony_ci { 1471e5c31af7Sopenharmony_ci const ShaderStageFlags required = SHADER_STAGE_VERTEX_BIT; 1472e5c31af7Sopenharmony_ci shaderStageRequired = (ShaderStageFlags)((deUint32)shaderStageRequired | ((deUint32)(shaderStageTested & required) ? 0u : (deUint32)required)); 1473e5c31af7Sopenharmony_ci } 1474e5c31af7Sopenharmony_ci 1475e5c31af7Sopenharmony_ci const deUint32 stagesCount = static_cast<deUint32>(stagesVector.size()); 1476e5c31af7Sopenharmony_ci const string vert = (shaderStageRequired & SHADER_STAGE_VERTEX_BIT) ? "vert_noSubgroup" : "vert"; 1477e5c31af7Sopenharmony_ci const string tesc = (shaderStageRequired & SHADER_STAGE_TESS_CONTROL_BIT) ? "tesc_noSubgroup" : "tesc"; 1478e5c31af7Sopenharmony_ci const string tese = (shaderStageRequired & SHADER_STAGE_TESS_EVALUATION_BIT) ? "tese_noSubgroup" : "tese"; 1479e5c31af7Sopenharmony_ci 1480e5c31af7Sopenharmony_ci shaderStageRequired = (ShaderStageFlags)(shaderStageTested | shaderStageRequired); 1481e5c31af7Sopenharmony_ci 1482e5c31af7Sopenharmony_ci const GlslSource *vshader = &context.getSourceCollection().get(vert); 1483e5c31af7Sopenharmony_ci const GlslSource *fshader = DE_NULL; 1484e5c31af7Sopenharmony_ci const GlslSource *gshader = DE_NULL; 1485e5c31af7Sopenharmony_ci const GlslSource *tcshader = DE_NULL; 1486e5c31af7Sopenharmony_ci const GlslSource *teshader = DE_NULL; 1487e5c31af7Sopenharmony_ci 1488e5c31af7Sopenharmony_ci if (shaderStageRequired & SHADER_STAGE_TESS_CONTROL_BIT) 1489e5c31af7Sopenharmony_ci { 1490e5c31af7Sopenharmony_ci tcshader = &context.getSourceCollection().get(tesc); 1491e5c31af7Sopenharmony_ci teshader = &context.getSourceCollection().get(tese); 1492e5c31af7Sopenharmony_ci } 1493e5c31af7Sopenharmony_ci if (shaderStageRequired & SHADER_STAGE_GEOMETRY_BIT) 1494e5c31af7Sopenharmony_ci { 1495e5c31af7Sopenharmony_ci if (shaderStageRequired & SHADER_STAGE_TESS_EVALUATION_BIT) 1496e5c31af7Sopenharmony_ci { 1497e5c31af7Sopenharmony_ci // tessellation shaders output line primitives 1498e5c31af7Sopenharmony_ci gshader = &context.getSourceCollection().get("geometry_lines"); 1499e5c31af7Sopenharmony_ci } 1500e5c31af7Sopenharmony_ci else 1501e5c31af7Sopenharmony_ci { 1502e5c31af7Sopenharmony_ci // otherwise points are processed by geometry shader 1503e5c31af7Sopenharmony_ci gshader = &context.getSourceCollection().get("geometry_points"); 1504e5c31af7Sopenharmony_ci } 1505e5c31af7Sopenharmony_ci } 1506e5c31af7Sopenharmony_ci if (shaderStageRequired & SHADER_STAGE_FRAGMENT_BIT) 1507e5c31af7Sopenharmony_ci { 1508e5c31af7Sopenharmony_ci fshader = &context.getSourceCollection().get("fragment"); 1509e5c31af7Sopenharmony_ci } 1510e5c31af7Sopenharmony_ci 1511e5c31af7Sopenharmony_ci std::vector< de::SharedPtr<BufferOrImage> > inputBuffers(stagesCount + extraDatasCount); 1512e5c31af7Sopenharmony_ci 1513e5c31af7Sopenharmony_ci // The implicit result SSBO we use to store our outputs from the shader 1514e5c31af7Sopenharmony_ci for (deUint32 ndx = 0u; ndx < stagesCount; ++ndx) 1515e5c31af7Sopenharmony_ci { 1516e5c31af7Sopenharmony_ci const deUint64 shaderSize = (stagesVector[ndx] == SHADER_STAGE_TESS_EVALUATION_BIT) ? maxWidth * 2 : maxWidth; 1517e5c31af7Sopenharmony_ci const deUint64 size = getElementSizeInBytes(format, SSBOData::LayoutStd430) * shaderSize; 1518e5c31af7Sopenharmony_ci inputBuffers[ndx] = de::SharedPtr<BufferOrImage>(new Buffer(context, size)); 1519e5c31af7Sopenharmony_ci 1520e5c31af7Sopenharmony_ci log << tcu::TestLog::Message 1521e5c31af7Sopenharmony_ci << "binding inputBuffers[" << ndx << "](" << inputBuffers[ndx]->getType() << ", " 1522e5c31af7Sopenharmony_ci << inputBuffers[ndx]->getId() << ", " << size << "), " 1523e5c31af7Sopenharmony_ci << "inputstage[" << ndx << "] = " << stagesVector[ndx] << " binding = " << getResultBinding(stagesVector[ndx]) 1524e5c31af7Sopenharmony_ci << tcu::TestLog::EndMessage; 1525e5c31af7Sopenharmony_ci 1526e5c31af7Sopenharmony_ci gl.bindBufferBase(inputBuffers[ndx]->getType(), getResultBinding(stagesVector[ndx]), inputBuffers[ndx]->getId()); 1527e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase(ndx, inputBuffers[ndx])"); 1528e5c31af7Sopenharmony_ci } 1529e5c31af7Sopenharmony_ci 1530e5c31af7Sopenharmony_ci for (deUint32 ndx = stagesCount; ndx < stagesCount + extraDatasCount; ++ndx) 1531e5c31af7Sopenharmony_ci { 1532e5c31af7Sopenharmony_ci const deUint32 datasNdx = ndx - stagesCount; 1533e5c31af7Sopenharmony_ci if (extraDatas[datasNdx].isImage) 1534e5c31af7Sopenharmony_ci { 1535e5c31af7Sopenharmony_ci inputBuffers[ndx] = de::SharedPtr<BufferOrImage>(new Image(context, static_cast<deUint32>(extraDatas[datasNdx].numElements), 1, extraDatas[datasNdx].format)); 1536e5c31af7Sopenharmony_ci 1537e5c31af7Sopenharmony_ci // haven't implemented init for images yet 1538e5c31af7Sopenharmony_ci DE_ASSERT(extraDatas[datasNdx].initializeType == subgroups::SSBOData::InitializeNone); 1539e5c31af7Sopenharmony_ci } 1540e5c31af7Sopenharmony_ci else 1541e5c31af7Sopenharmony_ci { 1542e5c31af7Sopenharmony_ci const deUint64 size = getElementSizeInBytes(extraDatas[datasNdx].format, extraDatas[datasNdx].layout) * extraDatas[datasNdx].numElements; 1543e5c31af7Sopenharmony_ci inputBuffers[ndx] = de::SharedPtr<BufferOrImage>(new Buffer(context, size)); 1544e5c31af7Sopenharmony_ci 1545e5c31af7Sopenharmony_ci glw::GLvoid *ptr = inputBuffers[ndx]->getAsBuffer()->mapBufferPtr(); 1546e5c31af7Sopenharmony_ci initializeMemory(context.getDeqpContext(), ptr, extraDatas[datasNdx]); 1547e5c31af7Sopenharmony_ci inputBuffers[ndx]->getAsBuffer()->unmapBufferPtr(); 1548e5c31af7Sopenharmony_ci } 1549e5c31af7Sopenharmony_ci 1550e5c31af7Sopenharmony_ci log << tcu::TestLog::Message 1551e5c31af7Sopenharmony_ci << "binding inputBuffers[" << ndx << "](" << inputBuffers[ndx]->getType() << ", " 1552e5c31af7Sopenharmony_ci << inputBuffers[ndx]->getId() << ", " << extraDatas[datasNdx].numElements << " els), " 1553e5c31af7Sopenharmony_ci << "extrastage[" << datasNdx << "] = " << extraDatas[datasNdx].stages << " binding = " << extraDatas[datasNdx].binding 1554e5c31af7Sopenharmony_ci << tcu::TestLog::EndMessage; 1555e5c31af7Sopenharmony_ci 1556e5c31af7Sopenharmony_ci if (inputBuffers[ndx]->isImage()) 1557e5c31af7Sopenharmony_ci { 1558e5c31af7Sopenharmony_ci gl.bindImageTexture(extraDatas[datasNdx].binding, inputBuffers[ndx]->getId(), 1559e5c31af7Sopenharmony_ci 0, GL_FALSE, 0, GL_READ_WRITE, extraDatas[datasNdx].format); 1560e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glBindImageTexture(extraDatas[datasNdx])"); 1561e5c31af7Sopenharmony_ci } else 1562e5c31af7Sopenharmony_ci { 1563e5c31af7Sopenharmony_ci gl.bindBufferBase(inputBuffers[ndx]->getType(), extraDatas[datasNdx].binding, inputBuffers[ndx]->getId()); 1564e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase(extraDatas[datasNdx])"); 1565e5c31af7Sopenharmony_ci } 1566e5c31af7Sopenharmony_ci } 1567e5c31af7Sopenharmony_ci 1568e5c31af7Sopenharmony_ci de::MovePtr<glu::ShaderProgram> pipeline( 1569e5c31af7Sopenharmony_ci makeGraphicsPipeline(context, shaderStageRequired, vshader, fshader, gshader, tcshader, teshader)); 1570e5c31af7Sopenharmony_ci 1571e5c31af7Sopenharmony_ci if (!pipeline->isOk()) 1572e5c31af7Sopenharmony_ci { 1573e5c31af7Sopenharmony_ci return tcu::TestStatus::fail("allstages graphics program build failed"); 1574e5c31af7Sopenharmony_ci } 1575e5c31af7Sopenharmony_ci 1576e5c31af7Sopenharmony_ci { 1577e5c31af7Sopenharmony_ci const deUint32 subgroupSize = getSubgroupSize(context); 1578e5c31af7Sopenharmony_ci unsigned totalIterations = 0u; 1579e5c31af7Sopenharmony_ci unsigned failedIterations = 0u; 1580e5c31af7Sopenharmony_ci Image resultImage (context, maxWidth, 1, format); 1581e5c31af7Sopenharmony_ci const deUint64 imageResultSize = getFormatSizeInBytes(format) * maxWidth; 1582e5c31af7Sopenharmony_ci vector<glw::GLubyte> imageBufferResult(imageResultSize); 1583e5c31af7Sopenharmony_ci 1584e5c31af7Sopenharmony_ci Vao vao(context); 1585e5c31af7Sopenharmony_ci Fbo fbo(context); 1586e5c31af7Sopenharmony_ci fbo.bind2D(resultImage); 1587e5c31af7Sopenharmony_ci 1588e5c31af7Sopenharmony_ci gl.viewport(0, 0, maxWidth, 1u); 1589e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "viewport"); 1590e5c31af7Sopenharmony_ci 1591e5c31af7Sopenharmony_ci for (deUint32 width = 1u; width < maxWidth; width = getNextWidth(width)) 1592e5c31af7Sopenharmony_ci { 1593e5c31af7Sopenharmony_ci for (deUint32 ndx = stagesCount; ndx < stagesCount + extraDatasCount; ++ndx) 1594e5c31af7Sopenharmony_ci { 1595e5c31af7Sopenharmony_ci // re-init the data 1596e5c31af7Sopenharmony_ci if (extraDatas[ndx - stagesCount].isImage) 1597e5c31af7Sopenharmony_ci { 1598e5c31af7Sopenharmony_ci // haven't implemented init for images yet 1599e5c31af7Sopenharmony_ci DE_ASSERT(extraDatas[ndx - stagesCount].initializeType == subgroups::SSBOData::InitializeNone); 1600e5c31af7Sopenharmony_ci } else 1601e5c31af7Sopenharmony_ci { 1602e5c31af7Sopenharmony_ci glw::GLvoid *ptr = inputBuffers[ndx]->getAsBuffer()->mapBufferPtr(); 1603e5c31af7Sopenharmony_ci initializeMemory(context.getDeqpContext(), ptr, extraDatas[ndx - stagesCount]); 1604e5c31af7Sopenharmony_ci inputBuffers[ndx]->getAsBuffer()->unmapBufferPtr(); 1605e5c31af7Sopenharmony_ci } 1606e5c31af7Sopenharmony_ci } 1607e5c31af7Sopenharmony_ci 1608e5c31af7Sopenharmony_ci totalIterations++; 1609e5c31af7Sopenharmony_ci 1610e5c31af7Sopenharmony_ci gl.clearColor(0.0f, 0.0f, 0.0f, 0.0f); 1611e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glClearColor"); 1612e5c31af7Sopenharmony_ci gl.clear(GL_COLOR_BUFFER_BIT); 1613e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glClear"); 1614e5c31af7Sopenharmony_ci 1615e5c31af7Sopenharmony_ci gl.useProgram(pipeline->getProgram()); 1616e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram"); 1617e5c31af7Sopenharmony_ci 1618e5c31af7Sopenharmony_ci glw::GLenum drawType; 1619e5c31af7Sopenharmony_ci if (shaderStageRequired & SHADER_STAGE_TESS_CONTROL_BIT) 1620e5c31af7Sopenharmony_ci { 1621e5c31af7Sopenharmony_ci drawType = GL_PATCHES; 1622e5c31af7Sopenharmony_ci gl.patchParameteri(GL_PATCH_VERTICES, 1u); 1623e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glPatchParameter(PATCH_VERTICES)"); 1624e5c31af7Sopenharmony_ci } else 1625e5c31af7Sopenharmony_ci { 1626e5c31af7Sopenharmony_ci drawType = GL_POINTS; 1627e5c31af7Sopenharmony_ci } 1628e5c31af7Sopenharmony_ci 1629e5c31af7Sopenharmony_ci gl.drawArrays(drawType, 0, width); 1630e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays"); 1631e5c31af7Sopenharmony_ci 1632e5c31af7Sopenharmony_ci GLenum readFormat; 1633e5c31af7Sopenharmony_ci GLenum readType; 1634e5c31af7Sopenharmony_ci getFormatReadInfo(format, readFormat, readType); 1635e5c31af7Sopenharmony_ci 1636e5c31af7Sopenharmony_ci gl.readPixels(0, 0, width, 1, readFormat, readType, (GLvoid*)&imageBufferResult[0]); 1637e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels"); 1638e5c31af7Sopenharmony_ci 1639e5c31af7Sopenharmony_ci for (deUint32 ndx = 0u; ndx < stagesCount; ++ndx) 1640e5c31af7Sopenharmony_ci { 1641e5c31af7Sopenharmony_ci std::vector<const void*> datas; 1642e5c31af7Sopenharmony_ci std::vector<Buffer *> buffersToUnmap; 1643e5c31af7Sopenharmony_ci 1644e5c31af7Sopenharmony_ci if (!inputBuffers[ndx]->isImage()) 1645e5c31af7Sopenharmony_ci { 1646e5c31af7Sopenharmony_ci glw::GLvoid * resultData = inputBuffers[ndx]->getAsBuffer()->mapBufferPtr(); 1647e5c31af7Sopenharmony_ci buffersToUnmap.push_back(inputBuffers[ndx]->getAsBuffer()); 1648e5c31af7Sopenharmony_ci // we always have our result data first 1649e5c31af7Sopenharmony_ci datas.push_back(resultData); 1650e5c31af7Sopenharmony_ci } 1651e5c31af7Sopenharmony_ci 1652e5c31af7Sopenharmony_ci for (deUint32 index = stagesCount; index < stagesCount + extraDatasCount; ++index) 1653e5c31af7Sopenharmony_ci { 1654e5c31af7Sopenharmony_ci const deUint32 datasNdx = index - stagesCount; 1655e5c31af7Sopenharmony_ci if ((stagesVector[ndx] & extraDatas[datasNdx].stages) && (!inputBuffers[index]->isImage())) 1656e5c31af7Sopenharmony_ci { 1657e5c31af7Sopenharmony_ci glw::GLvoid * resultData = inputBuffers[index]->getAsBuffer()->mapBufferPtr(); 1658e5c31af7Sopenharmony_ci buffersToUnmap.push_back(inputBuffers[index]->getAsBuffer()); 1659e5c31af7Sopenharmony_ci datas.push_back(resultData); 1660e5c31af7Sopenharmony_ci } 1661e5c31af7Sopenharmony_ci } 1662e5c31af7Sopenharmony_ci 1663e5c31af7Sopenharmony_ci if (!checkResult(datas, (stagesVector[ndx] == SHADER_STAGE_TESS_EVALUATION_BIT) ? width * 2 : width , subgroupSize)) 1664e5c31af7Sopenharmony_ci failedIterations++; 1665e5c31af7Sopenharmony_ci 1666e5c31af7Sopenharmony_ci while( !buffersToUnmap.empty() ) 1667e5c31af7Sopenharmony_ci { 1668e5c31af7Sopenharmony_ci Buffer * buf = buffersToUnmap.back(); 1669e5c31af7Sopenharmony_ci buf->unmapBufferPtr(); 1670e5c31af7Sopenharmony_ci buffersToUnmap.pop_back(); 1671e5c31af7Sopenharmony_ci } 1672e5c31af7Sopenharmony_ci } 1673e5c31af7Sopenharmony_ci if (shaderStageTested & SHADER_STAGE_FRAGMENT_BIT) 1674e5c31af7Sopenharmony_ci { 1675e5c31af7Sopenharmony_ci std::vector<const void*> datas; 1676e5c31af7Sopenharmony_ci std::vector<Buffer *> buffersToUnmap; 1677e5c31af7Sopenharmony_ci 1678e5c31af7Sopenharmony_ci // we always have our result data first 1679e5c31af7Sopenharmony_ci datas.push_back(&imageBufferResult[0]); 1680e5c31af7Sopenharmony_ci 1681e5c31af7Sopenharmony_ci for (deUint32 index = stagesCount; index < stagesCount + extraDatasCount; ++index) 1682e5c31af7Sopenharmony_ci { 1683e5c31af7Sopenharmony_ci const deUint32 datasNdx = index - stagesCount; 1684e5c31af7Sopenharmony_ci if (SHADER_STAGE_FRAGMENT_BIT & extraDatas[datasNdx].stages && (!inputBuffers[index]->isImage())) 1685e5c31af7Sopenharmony_ci { 1686e5c31af7Sopenharmony_ci glw::GLvoid * resultData = inputBuffers[index]->getAsBuffer()->mapBufferPtr(); 1687e5c31af7Sopenharmony_ci buffersToUnmap.push_back(inputBuffers[index]->getAsBuffer()); 1688e5c31af7Sopenharmony_ci // we always have our result data first 1689e5c31af7Sopenharmony_ci datas.push_back(resultData); 1690e5c31af7Sopenharmony_ci } 1691e5c31af7Sopenharmony_ci } 1692e5c31af7Sopenharmony_ci 1693e5c31af7Sopenharmony_ci if (!checkResult(datas, width, subgroupSize)) 1694e5c31af7Sopenharmony_ci failedIterations++; 1695e5c31af7Sopenharmony_ci 1696e5c31af7Sopenharmony_ci while( !buffersToUnmap.empty() ) 1697e5c31af7Sopenharmony_ci { 1698e5c31af7Sopenharmony_ci Buffer * buf = buffersToUnmap.back(); 1699e5c31af7Sopenharmony_ci buf->unmapBufferPtr(); 1700e5c31af7Sopenharmony_ci buffersToUnmap.pop_back(); 1701e5c31af7Sopenharmony_ci } 1702e5c31af7Sopenharmony_ci } 1703e5c31af7Sopenharmony_ci 1704e5c31af7Sopenharmony_ci } 1705e5c31af7Sopenharmony_ci 1706e5c31af7Sopenharmony_ci if (0 < failedIterations) 1707e5c31af7Sopenharmony_ci { 1708e5c31af7Sopenharmony_ci log << tcu::TestLog::Message << (totalIterations - failedIterations) << " / " 1709e5c31af7Sopenharmony_ci << totalIterations << " values passed" << tcu::TestLog::EndMessage; 1710e5c31af7Sopenharmony_ci return tcu::TestStatus::fail("Failed!"); 1711e5c31af7Sopenharmony_ci } else 1712e5c31af7Sopenharmony_ci { 1713e5c31af7Sopenharmony_ci log << tcu::TestLog::Message << (totalIterations - failedIterations) << " / " 1714e5c31af7Sopenharmony_ci << totalIterations << " values passed" << tcu::TestLog::EndMessage; 1715e5c31af7Sopenharmony_ci } 1716e5c31af7Sopenharmony_ci } 1717e5c31af7Sopenharmony_ci return tcu::TestStatus::pass("OK"); 1718e5c31af7Sopenharmony_ci} 1719e5c31af7Sopenharmony_ci 1720e5c31af7Sopenharmony_citcu::TestStatus glc::subgroups::makeVertexFrameBufferTest(Context& context, Format format, 1721e5c31af7Sopenharmony_ci SSBOData* extraData, deUint32 extraDataCount, 1722e5c31af7Sopenharmony_ci bool (*checkResult)(std::vector<const void*> datas, deUint32 width, deUint32 subgroupSize)) 1723e5c31af7Sopenharmony_ci{ 1724e5c31af7Sopenharmony_ci tcu::TestLog& log = context.getDeqpContext().getTestContext().getLog(); 1725e5c31af7Sopenharmony_ci const glw::Functions& gl = context.getDeqpContext().getRenderContext().getFunctions(); 1726e5c31af7Sopenharmony_ci 1727e5c31af7Sopenharmony_ci const deUint32 maxWidth = getMaxWidth(); 1728e5c31af7Sopenharmony_ci vector<de::SharedPtr<BufferOrImage> > inputBuffers (extraDataCount); 1729e5c31af7Sopenharmony_ci 1730e5c31af7Sopenharmony_ci const GlslSource& vshader = context.getSourceCollection().get("vert"); 1731e5c31af7Sopenharmony_ci const GlslSource& fshader = context.getSourceCollection().get("fragment"); 1732e5c31af7Sopenharmony_ci 1733e5c31af7Sopenharmony_ci for (deUint32 i = 0u; i < extraDataCount; i++) 1734e5c31af7Sopenharmony_ci { 1735e5c31af7Sopenharmony_ci if (extraData[i].isImage) 1736e5c31af7Sopenharmony_ci { 1737e5c31af7Sopenharmony_ci inputBuffers[i] = de::SharedPtr<BufferOrImage>(new Image(context, static_cast<deUint32>(extraData[i].numElements), 1u, extraData[i].format)); 1738e5c31af7Sopenharmony_ci 1739e5c31af7Sopenharmony_ci // haven't implemented init for images yet 1740e5c31af7Sopenharmony_ci DE_ASSERT(extraData[i].initializeType == subgroups::SSBOData::InitializeNone); 1741e5c31af7Sopenharmony_ci } 1742e5c31af7Sopenharmony_ci else 1743e5c31af7Sopenharmony_ci { 1744e5c31af7Sopenharmony_ci deUint64 size = getElementSizeInBytes(extraData[i].format, extraData[i].layout) * extraData[i].numElements; 1745e5c31af7Sopenharmony_ci inputBuffers[i] = de::SharedPtr<BufferOrImage>(new Buffer(context, size, GL_UNIFORM_BUFFER)); 1746e5c31af7Sopenharmony_ci 1747e5c31af7Sopenharmony_ci glw::GLvoid *ptr = inputBuffers[i]->getAsBuffer()->mapBufferPtr(); 1748e5c31af7Sopenharmony_ci initializeMemory(context.getDeqpContext(), ptr, extraData[i]); 1749e5c31af7Sopenharmony_ci inputBuffers[i]->getAsBuffer()->unmapBufferPtr(); 1750e5c31af7Sopenharmony_ci } 1751e5c31af7Sopenharmony_ci } 1752e5c31af7Sopenharmony_ci 1753e5c31af7Sopenharmony_ci for (deUint32 ndx = 0u; ndx < extraDataCount; ndx++) 1754e5c31af7Sopenharmony_ci { 1755e5c31af7Sopenharmony_ci log << tcu::TestLog::Message 1756e5c31af7Sopenharmony_ci << "binding inputBuffers[" << ndx << "](" << inputBuffers[ndx]->getType() << ", " << inputBuffers[ndx]->getId() << " ), " 1757e5c31af7Sopenharmony_ci << "VERTEX, binding = " << extraData[ndx].binding << "\n" 1758e5c31af7Sopenharmony_ci << tcu::TestLog::EndMessage; 1759e5c31af7Sopenharmony_ci 1760e5c31af7Sopenharmony_ci if (inputBuffers[ndx]->isImage()) 1761e5c31af7Sopenharmony_ci { 1762e5c31af7Sopenharmony_ci gl.bindImageTexture(extraData[ndx].binding, inputBuffers[ndx]->getId(), 1763e5c31af7Sopenharmony_ci 0, GL_FALSE, 0, GL_READ_ONLY, extraData[ndx].format); 1764e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glBindImageTexture()"); 1765e5c31af7Sopenharmony_ci } else 1766e5c31af7Sopenharmony_ci { 1767e5c31af7Sopenharmony_ci gl.bindBufferBase(inputBuffers[ndx]->getType(), extraData[ndx].binding, inputBuffers[ndx]->getId()); 1768e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase()"); 1769e5c31af7Sopenharmony_ci } 1770e5c31af7Sopenharmony_ci } 1771e5c31af7Sopenharmony_ci 1772e5c31af7Sopenharmony_ci de::MovePtr<glu::ShaderProgram> pipeline( 1773e5c31af7Sopenharmony_ci makeGraphicsPipeline(context, (ShaderStageFlags)(SHADER_STAGE_VERTEX_BIT | SHADER_STAGE_FRAGMENT_BIT), 1774e5c31af7Sopenharmony_ci &vshader, &fshader, DE_NULL, DE_NULL, DE_NULL)); 1775e5c31af7Sopenharmony_ci 1776e5c31af7Sopenharmony_ci if (!pipeline->isOk()) 1777e5c31af7Sopenharmony_ci { 1778e5c31af7Sopenharmony_ci return tcu::TestStatus::fail("vert graphics program build failed"); 1779e5c31af7Sopenharmony_ci } 1780e5c31af7Sopenharmony_ci 1781e5c31af7Sopenharmony_ci const deUint32 subgroupSize = getSubgroupSize(context); 1782e5c31af7Sopenharmony_ci 1783e5c31af7Sopenharmony_ci const deUint64 vertexBufferSize = maxWidth * sizeof(tcu::Vec4); 1784e5c31af7Sopenharmony_ci Buffer vertexBuffer (context, vertexBufferSize, GL_ARRAY_BUFFER); 1785e5c31af7Sopenharmony_ci 1786e5c31af7Sopenharmony_ci unsigned totalIterations = 0u; 1787e5c31af7Sopenharmony_ci unsigned failedIterations = 0u; 1788e5c31af7Sopenharmony_ci 1789e5c31af7Sopenharmony_ci Image discardableImage (context, maxWidth, 1u, format); 1790e5c31af7Sopenharmony_ci 1791e5c31af7Sopenharmony_ci { 1792e5c31af7Sopenharmony_ci glw::GLvoid * bufferPtr = vertexBuffer.mapBufferPtr(); 1793e5c31af7Sopenharmony_ci std::vector<tcu::Vec4> data (maxWidth, tcu::Vec4(1.0f, 0.5f, 1.0f, 1.0f)); 1794e5c31af7Sopenharmony_ci const float pixelSize = 2.0f / static_cast<float>(maxWidth); 1795e5c31af7Sopenharmony_ci float leftHandPosition = -1.0f; 1796e5c31af7Sopenharmony_ci 1797e5c31af7Sopenharmony_ci for(deUint32 ndx = 0u; ndx < maxWidth; ++ndx) 1798e5c31af7Sopenharmony_ci { 1799e5c31af7Sopenharmony_ci data[ndx][0] = leftHandPosition + pixelSize / 2.0f; 1800e5c31af7Sopenharmony_ci leftHandPosition += pixelSize; 1801e5c31af7Sopenharmony_ci } 1802e5c31af7Sopenharmony_ci 1803e5c31af7Sopenharmony_ci deMemcpy(bufferPtr, &data[0], maxWidth * sizeof(tcu::Vec4)); 1804e5c31af7Sopenharmony_ci vertexBuffer.unmapBufferPtr(); 1805e5c31af7Sopenharmony_ci } 1806e5c31af7Sopenharmony_ci 1807e5c31af7Sopenharmony_ci Vao vao(context); 1808e5c31af7Sopenharmony_ci Fbo fbo(context); 1809e5c31af7Sopenharmony_ci fbo.bind2D(discardableImage); 1810e5c31af7Sopenharmony_ci 1811e5c31af7Sopenharmony_ci gl.viewport(0, 0, maxWidth, 1u); 1812e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport"); 1813e5c31af7Sopenharmony_ci 1814e5c31af7Sopenharmony_ci const deUint64 imageResultSize = getFormatSizeInBytes(format) * maxWidth; 1815e5c31af7Sopenharmony_ci vector<glw::GLubyte> imageBufferResult(imageResultSize); 1816e5c31af7Sopenharmony_ci const deUint64 vertexBufferOffset = 0u; 1817e5c31af7Sopenharmony_ci 1818e5c31af7Sopenharmony_ci for (deUint32 width = 1u; width < maxWidth; width = getNextWidth(width)) 1819e5c31af7Sopenharmony_ci { 1820e5c31af7Sopenharmony_ci totalIterations++; 1821e5c31af7Sopenharmony_ci 1822e5c31af7Sopenharmony_ci for (deUint32 ndx = 0u; ndx < inputBuffers.size(); ndx++) 1823e5c31af7Sopenharmony_ci { 1824e5c31af7Sopenharmony_ci if (inputBuffers[ndx]->isImage()) 1825e5c31af7Sopenharmony_ci { 1826e5c31af7Sopenharmony_ci DE_ASSERT(extraData[ndx].initializeType == subgroups::SSBOData::InitializeNone); 1827e5c31af7Sopenharmony_ci } else 1828e5c31af7Sopenharmony_ci { 1829e5c31af7Sopenharmony_ci glw::GLvoid *ptr = inputBuffers[ndx]->getAsBuffer()->mapBufferPtr(); 1830e5c31af7Sopenharmony_ci initializeMemory(context.getDeqpContext(), ptr, extraData[ndx]); 1831e5c31af7Sopenharmony_ci inputBuffers[ndx]->getAsBuffer()->unmapBufferPtr(); 1832e5c31af7Sopenharmony_ci } 1833e5c31af7Sopenharmony_ci } 1834e5c31af7Sopenharmony_ci 1835e5c31af7Sopenharmony_ci { 1836e5c31af7Sopenharmony_ci gl.clearColor(0.0f, 0.0f, 0.0f, 0.0f); 1837e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glClearColor"); 1838e5c31af7Sopenharmony_ci gl.clear(GL_COLOR_BUFFER_BIT); 1839e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glClear"); 1840e5c31af7Sopenharmony_ci 1841e5c31af7Sopenharmony_ci gl.useProgram(pipeline->getProgram()); 1842e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram"); 1843e5c31af7Sopenharmony_ci 1844e5c31af7Sopenharmony_ci gl.enableVertexAttribArray(0); 1845e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray"); 1846e5c31af7Sopenharmony_ci 1847e5c31af7Sopenharmony_ci gl.bindBuffer(GL_ARRAY_BUFFER, vertexBuffer.getId()); 1848e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer"); 1849e5c31af7Sopenharmony_ci 1850e5c31af7Sopenharmony_ci gl.vertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(tcu::Vec4), glu::BufferOffsetAsPointer(vertexBufferOffset)); 1851e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer"); 1852e5c31af7Sopenharmony_ci 1853e5c31af7Sopenharmony_ci gl.drawArrays(GL_POINTS, 0, width); 1854e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays"); 1855e5c31af7Sopenharmony_ci 1856e5c31af7Sopenharmony_ci gl.disableVertexAttribArray(0); 1857e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glDisableVertexAttribArray"); 1858e5c31af7Sopenharmony_ci 1859e5c31af7Sopenharmony_ci GLenum readFormat; 1860e5c31af7Sopenharmony_ci GLenum readType; 1861e5c31af7Sopenharmony_ci getFormatReadInfo(format, readFormat, readType); 1862e5c31af7Sopenharmony_ci 1863e5c31af7Sopenharmony_ci gl.readPixels(0, 0, width, 1, readFormat, readType, (GLvoid*)&imageBufferResult[0]); 1864e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels"); 1865e5c31af7Sopenharmony_ci } 1866e5c31af7Sopenharmony_ci 1867e5c31af7Sopenharmony_ci { 1868e5c31af7Sopenharmony_ci std::vector<const void*> datas; 1869e5c31af7Sopenharmony_ci datas.push_back(&imageBufferResult[0]); 1870e5c31af7Sopenharmony_ci if (!checkResult(datas, width, subgroupSize)) 1871e5c31af7Sopenharmony_ci failedIterations++; 1872e5c31af7Sopenharmony_ci } 1873e5c31af7Sopenharmony_ci } 1874e5c31af7Sopenharmony_ci 1875e5c31af7Sopenharmony_ci if (0 < failedIterations) 1876e5c31af7Sopenharmony_ci { 1877e5c31af7Sopenharmony_ci log << tcu::TestLog::Message << (totalIterations - failedIterations) << " / " 1878e5c31af7Sopenharmony_ci << totalIterations << " values passed" << tcu::TestLog::EndMessage; 1879e5c31af7Sopenharmony_ci return tcu::TestStatus::fail("Failed!"); 1880e5c31af7Sopenharmony_ci } else 1881e5c31af7Sopenharmony_ci { 1882e5c31af7Sopenharmony_ci log << tcu::TestLog::Message << (totalIterations - failedIterations) << " / " 1883e5c31af7Sopenharmony_ci <<totalIterations << " values passed" << tcu::TestLog::EndMessage; 1884e5c31af7Sopenharmony_ci } 1885e5c31af7Sopenharmony_ci 1886e5c31af7Sopenharmony_ci return tcu::TestStatus::pass("OK"); 1887e5c31af7Sopenharmony_ci} 1888e5c31af7Sopenharmony_ci 1889e5c31af7Sopenharmony_ci 1890e5c31af7Sopenharmony_citcu::TestStatus glc::subgroups::makeFragmentFrameBufferTest (Context& context, Format format, SSBOData* extraDatas, 1891e5c31af7Sopenharmony_ci deUint32 extraDatasCount, 1892e5c31af7Sopenharmony_ci bool (*checkResult)(std::vector<const void*> datas, deUint32 width, 1893e5c31af7Sopenharmony_ci deUint32 height, deUint32 subgroupSize)) 1894e5c31af7Sopenharmony_ci{ 1895e5c31af7Sopenharmony_ci tcu::TestLog& log = context.getDeqpContext().getTestContext().getLog(); 1896e5c31af7Sopenharmony_ci const glw::Functions& gl = context.getDeqpContext().getRenderContext().getFunctions(); 1897e5c31af7Sopenharmony_ci 1898e5c31af7Sopenharmony_ci const GlslSource& vshader = context.getSourceCollection().get("vert"); 1899e5c31af7Sopenharmony_ci const GlslSource& fshader = context.getSourceCollection().get("fragment"); 1900e5c31af7Sopenharmony_ci 1901e5c31af7Sopenharmony_ci std::vector< de::SharedPtr<BufferOrImage> > inputBuffers(extraDatasCount); 1902e5c31af7Sopenharmony_ci 1903e5c31af7Sopenharmony_ci for (deUint32 i = 0; i < extraDatasCount; i++) 1904e5c31af7Sopenharmony_ci { 1905e5c31af7Sopenharmony_ci if (extraDatas[i].isImage) 1906e5c31af7Sopenharmony_ci { 1907e5c31af7Sopenharmony_ci inputBuffers[i] = de::SharedPtr<BufferOrImage>(new Image(context, 1908e5c31af7Sopenharmony_ci static_cast<deUint32>(extraDatas[i].numElements), 1, extraDatas[i].format)); 1909e5c31af7Sopenharmony_ci 1910e5c31af7Sopenharmony_ci // haven't implemented init for images yet 1911e5c31af7Sopenharmony_ci DE_ASSERT(extraDatas[i].initializeType == subgroups::SSBOData::InitializeNone); 1912e5c31af7Sopenharmony_ci } 1913e5c31af7Sopenharmony_ci else 1914e5c31af7Sopenharmony_ci { 1915e5c31af7Sopenharmony_ci deUint64 size = 1916e5c31af7Sopenharmony_ci getElementSizeInBytes(extraDatas[i].format, extraDatas[i].layout) * extraDatas[i].numElements; 1917e5c31af7Sopenharmony_ci inputBuffers[i] = de::SharedPtr<BufferOrImage>(new Buffer(context, size, GL_UNIFORM_BUFFER)); 1918e5c31af7Sopenharmony_ci 1919e5c31af7Sopenharmony_ci glw::GLvoid *ptr = inputBuffers[i]->getAsBuffer()->mapBufferPtr(); 1920e5c31af7Sopenharmony_ci initializeMemory(context.getDeqpContext(), ptr, extraDatas[i]); 1921e5c31af7Sopenharmony_ci inputBuffers[i]->getAsBuffer()->unmapBufferPtr(); 1922e5c31af7Sopenharmony_ci } 1923e5c31af7Sopenharmony_ci } 1924e5c31af7Sopenharmony_ci 1925e5c31af7Sopenharmony_ci for (deUint32 i = 0; i < extraDatasCount; i++) 1926e5c31af7Sopenharmony_ci { 1927e5c31af7Sopenharmony_ci log << tcu::TestLog::Message 1928e5c31af7Sopenharmony_ci << "binding inputBuffers[" << i << "](" << inputBuffers[i]->getType() << ", " << inputBuffers[i]->getId() << " ), " 1929e5c31af7Sopenharmony_ci << "FRAGMENT, binding = " << extraDatas[i].binding << "\n" 1930e5c31af7Sopenharmony_ci << tcu::TestLog::EndMessage; 1931e5c31af7Sopenharmony_ci 1932e5c31af7Sopenharmony_ci if (inputBuffers[i]->isImage()) 1933e5c31af7Sopenharmony_ci { 1934e5c31af7Sopenharmony_ci gl.bindImageTexture(extraDatas[i].binding, inputBuffers[i]->getId(), 1935e5c31af7Sopenharmony_ci 0, GL_FALSE, 0, GL_READ_ONLY, extraDatas[i].format); 1936e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glBindImageTexture()"); 1937e5c31af7Sopenharmony_ci } else 1938e5c31af7Sopenharmony_ci { 1939e5c31af7Sopenharmony_ci gl.bindBufferBase(inputBuffers[i]->getType(), extraDatas[i].binding, inputBuffers[i]->getId()); 1940e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase()"); 1941e5c31af7Sopenharmony_ci } 1942e5c31af7Sopenharmony_ci } 1943e5c31af7Sopenharmony_ci 1944e5c31af7Sopenharmony_ci de::MovePtr<glu::ShaderProgram> pipeline( 1945e5c31af7Sopenharmony_ci makeGraphicsPipeline(context, (ShaderStageFlags)(SHADER_STAGE_VERTEX_BIT | SHADER_STAGE_FRAGMENT_BIT), 1946e5c31af7Sopenharmony_ci &vshader, &fshader, DE_NULL, DE_NULL, DE_NULL)); 1947e5c31af7Sopenharmony_ci 1948e5c31af7Sopenharmony_ci if (!pipeline->isOk()) 1949e5c31af7Sopenharmony_ci { 1950e5c31af7Sopenharmony_ci return tcu::TestStatus::fail("frag graphics program build failed"); 1951e5c31af7Sopenharmony_ci } 1952e5c31af7Sopenharmony_ci 1953e5c31af7Sopenharmony_ci const deUint32 subgroupSize = getSubgroupSize(context); 1954e5c31af7Sopenharmony_ci 1955e5c31af7Sopenharmony_ci unsigned totalIterations = 0; 1956e5c31af7Sopenharmony_ci unsigned failedIterations = 0; 1957e5c31af7Sopenharmony_ci 1958e5c31af7Sopenharmony_ci Vao vao(context); 1959e5c31af7Sopenharmony_ci Fbo fbo(context); 1960e5c31af7Sopenharmony_ci 1961e5c31af7Sopenharmony_ci for (deUint32 width = 8; width <= subgroupSize; width *= 2) 1962e5c31af7Sopenharmony_ci { 1963e5c31af7Sopenharmony_ci for (deUint32 height = 8; height <= subgroupSize; height *= 2) 1964e5c31af7Sopenharmony_ci { 1965e5c31af7Sopenharmony_ci totalIterations++; 1966e5c31af7Sopenharmony_ci 1967e5c31af7Sopenharmony_ci // re-init the data 1968e5c31af7Sopenharmony_ci for (deUint32 i = 0; i < extraDatasCount; i++) 1969e5c31af7Sopenharmony_ci { 1970e5c31af7Sopenharmony_ci if (inputBuffers[i]->isImage()) 1971e5c31af7Sopenharmony_ci { 1972e5c31af7Sopenharmony_ci DE_ASSERT(extraDatas[i].initializeType == subgroups::SSBOData::InitializeNone); 1973e5c31af7Sopenharmony_ci } else 1974e5c31af7Sopenharmony_ci { 1975e5c31af7Sopenharmony_ci glw::GLvoid *ptr = inputBuffers[i]->getAsBuffer()->mapBufferPtr(); 1976e5c31af7Sopenharmony_ci initializeMemory(context.getDeqpContext(), ptr, extraDatas[i]); 1977e5c31af7Sopenharmony_ci inputBuffers[i]->getAsBuffer()->unmapBufferPtr(); 1978e5c31af7Sopenharmony_ci } 1979e5c31af7Sopenharmony_ci } 1980e5c31af7Sopenharmony_ci 1981e5c31af7Sopenharmony_ci deUint64 formatSize = getFormatSizeInBytes(format); 1982e5c31af7Sopenharmony_ci const deUint64 resultImageSizeInBytes = 1983e5c31af7Sopenharmony_ci width * height * formatSize; 1984e5c31af7Sopenharmony_ci 1985e5c31af7Sopenharmony_ci Image resultImage(context, width, height, format); 1986e5c31af7Sopenharmony_ci 1987e5c31af7Sopenharmony_ci vector<glw::GLubyte> resultBuffer(resultImageSizeInBytes); 1988e5c31af7Sopenharmony_ci 1989e5c31af7Sopenharmony_ci fbo.bind2D(resultImage); 1990e5c31af7Sopenharmony_ci 1991e5c31af7Sopenharmony_ci gl.viewport(0, 0, width, height); 1992e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport"); 1993e5c31af7Sopenharmony_ci 1994e5c31af7Sopenharmony_ci gl.clearColor(0.0f, 0.0f, 0.0f, 0.0f); 1995e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glClearColor"); 1996e5c31af7Sopenharmony_ci gl.clear(GL_COLOR_BUFFER_BIT); 1997e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glClear"); 1998e5c31af7Sopenharmony_ci 1999e5c31af7Sopenharmony_ci gl.useProgram(pipeline->getProgram()); 2000e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram"); 2001e5c31af7Sopenharmony_ci 2002e5c31af7Sopenharmony_ci gl.drawArrays(GL_TRIANGLE_STRIP, 0, 4); 2003e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays"); 2004e5c31af7Sopenharmony_ci 2005e5c31af7Sopenharmony_ci GLenum readFormat; 2006e5c31af7Sopenharmony_ci GLenum readType; 2007e5c31af7Sopenharmony_ci getFormatReadInfo(format, readFormat, readType); 2008e5c31af7Sopenharmony_ci 2009e5c31af7Sopenharmony_ci gl.readPixels(0, 0, width, height, readFormat, readType, (GLvoid*)&resultBuffer[0]); 2010e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels"); 2011e5c31af7Sopenharmony_ci 2012e5c31af7Sopenharmony_ci std::vector<const void*> datas; 2013e5c31af7Sopenharmony_ci { 2014e5c31af7Sopenharmony_ci // we always have our result data first 2015e5c31af7Sopenharmony_ci datas.push_back(&resultBuffer[0]); 2016e5c31af7Sopenharmony_ci } 2017e5c31af7Sopenharmony_ci 2018e5c31af7Sopenharmony_ci if (!checkResult(datas, width, height, subgroupSize)) 2019e5c31af7Sopenharmony_ci { 2020e5c31af7Sopenharmony_ci failedIterations++; 2021e5c31af7Sopenharmony_ci } 2022e5c31af7Sopenharmony_ci } 2023e5c31af7Sopenharmony_ci } 2024e5c31af7Sopenharmony_ci 2025e5c31af7Sopenharmony_ci if (0 < failedIterations) 2026e5c31af7Sopenharmony_ci { 2027e5c31af7Sopenharmony_ci log << tcu::TestLog::Message << (totalIterations - failedIterations) << " / " 2028e5c31af7Sopenharmony_ci << totalIterations << " values passed" << tcu::TestLog::EndMessage; 2029e5c31af7Sopenharmony_ci return tcu::TestStatus::fail("Failed!"); 2030e5c31af7Sopenharmony_ci } else 2031e5c31af7Sopenharmony_ci { 2032e5c31af7Sopenharmony_ci log << tcu::TestLog::Message << (totalIterations - failedIterations) << " / " 2033e5c31af7Sopenharmony_ci <<totalIterations << " values passed" << tcu::TestLog::EndMessage; 2034e5c31af7Sopenharmony_ci } 2035e5c31af7Sopenharmony_ci return tcu::TestStatus::pass("OK"); 2036e5c31af7Sopenharmony_ci} 2037e5c31af7Sopenharmony_ci 2038e5c31af7Sopenharmony_citcu::TestStatus glc::subgroups::makeComputeTest( 2039e5c31af7Sopenharmony_ci Context& context, Format format, SSBOData* inputs, deUint32 inputsCount, 2040e5c31af7Sopenharmony_ci bool (*checkResult)(std::vector<const void*> datas, 2041e5c31af7Sopenharmony_ci const deUint32 numWorkgroups[3], const deUint32 localSize[3], 2042e5c31af7Sopenharmony_ci deUint32 subgroupSize)) 2043e5c31af7Sopenharmony_ci{ 2044e5c31af7Sopenharmony_ci const glw::Functions& gl = context.getDeqpContext().getRenderContext().getFunctions(); 2045e5c31af7Sopenharmony_ci deUint64 elementSize = getFormatSizeInBytes(format); 2046e5c31af7Sopenharmony_ci 2047e5c31af7Sopenharmony_ci const deUint64 resultBufferSize = maxSupportedSubgroupSize() * 2048e5c31af7Sopenharmony_ci maxSupportedSubgroupSize() * 2049e5c31af7Sopenharmony_ci maxSupportedSubgroupSize(); 2050e5c31af7Sopenharmony_ci const deUint64 resultBufferSizeInBytes = resultBufferSize * elementSize; 2051e5c31af7Sopenharmony_ci 2052e5c31af7Sopenharmony_ci Buffer resultBuffer( 2053e5c31af7Sopenharmony_ci context, resultBufferSizeInBytes); 2054e5c31af7Sopenharmony_ci 2055e5c31af7Sopenharmony_ci std::vector< de::SharedPtr<BufferOrImage> > inputBuffers(inputsCount); 2056e5c31af7Sopenharmony_ci 2057e5c31af7Sopenharmony_ci for (deUint32 i = 0; i < inputsCount; i++) 2058e5c31af7Sopenharmony_ci { 2059e5c31af7Sopenharmony_ci if (inputs[i].isImage) 2060e5c31af7Sopenharmony_ci { 2061e5c31af7Sopenharmony_ci inputBuffers[i] = de::SharedPtr<BufferOrImage>(new Image(context, 2062e5c31af7Sopenharmony_ci static_cast<deUint32>(inputs[i].numElements), 1, inputs[i].format)); 2063e5c31af7Sopenharmony_ci // haven't implemented init for images yet 2064e5c31af7Sopenharmony_ci DE_ASSERT(inputs[i].initializeType == subgroups::SSBOData::InitializeNone); 2065e5c31af7Sopenharmony_ci } 2066e5c31af7Sopenharmony_ci else 2067e5c31af7Sopenharmony_ci { 2068e5c31af7Sopenharmony_ci deUint64 size = 2069e5c31af7Sopenharmony_ci getElementSizeInBytes(inputs[i].format, inputs[i].layout) * inputs[i].numElements; 2070e5c31af7Sopenharmony_ci inputBuffers[i] = de::SharedPtr<BufferOrImage>(new Buffer(context, size)); 2071e5c31af7Sopenharmony_ci 2072e5c31af7Sopenharmony_ci glw::GLvoid *ptr = inputBuffers[i]->getAsBuffer()->mapBufferPtr(); 2073e5c31af7Sopenharmony_ci initializeMemory(context.getDeqpContext(), ptr, inputs[i]); 2074e5c31af7Sopenharmony_ci inputBuffers[i]->getAsBuffer()->unmapBufferPtr(); 2075e5c31af7Sopenharmony_ci } 2076e5c31af7Sopenharmony_ci 2077e5c31af7Sopenharmony_ci } 2078e5c31af7Sopenharmony_ci 2079e5c31af7Sopenharmony_ci tcu::TestLog& log = context.getDeqpContext().getTestContext().getLog(); 2080e5c31af7Sopenharmony_ci log << tcu::TestLog::Message 2081e5c31af7Sopenharmony_ci << "binding resultbuffer(type=" << resultBuffer.getType() 2082e5c31af7Sopenharmony_ci << ", id=" << resultBuffer.getId() << ", binding=0), COMPUTE" 2083e5c31af7Sopenharmony_ci << tcu::TestLog::EndMessage; 2084e5c31af7Sopenharmony_ci 2085e5c31af7Sopenharmony_ci gl.bindBufferBase(resultBuffer.getType(), 0, resultBuffer.getId()); 2086e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase(0, resultBuffer)"); 2087e5c31af7Sopenharmony_ci 2088e5c31af7Sopenharmony_ci for (deUint32 i = 0; i < inputsCount; i++) 2089e5c31af7Sopenharmony_ci { 2090e5c31af7Sopenharmony_ci log << tcu::TestLog::Message 2091e5c31af7Sopenharmony_ci << "binding inputBuffers[" << i << "](type=" << inputBuffers[i]->getType() 2092e5c31af7Sopenharmony_ci << ", id=" << inputBuffers[i]->getId() << ", binding=" 2093e5c31af7Sopenharmony_ci << inputs[i].binding << "), 1, COMPUTE" 2094e5c31af7Sopenharmony_ci << tcu::TestLog::EndMessage; 2095e5c31af7Sopenharmony_ci 2096e5c31af7Sopenharmony_ci if (inputBuffers[i]->isImage()) 2097e5c31af7Sopenharmony_ci { 2098e5c31af7Sopenharmony_ci gl.bindImageTexture(inputs[i].binding, inputBuffers[i]->getId(), 2099e5c31af7Sopenharmony_ci 0, GL_FALSE, 0, GL_READ_WRITE, inputs[i].format); 2100e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glBindImageTexture(inputBuffer[i]"); 2101e5c31af7Sopenharmony_ci } else 2102e5c31af7Sopenharmony_ci { 2103e5c31af7Sopenharmony_ci gl.bindBufferBase(inputBuffers[i]->getType(), inputs[i].binding, inputBuffers[i]->getId()); 2104e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase(inputBuffer[i])"); 2105e5c31af7Sopenharmony_ci } 2106e5c31af7Sopenharmony_ci } 2107e5c31af7Sopenharmony_ci 2108e5c31af7Sopenharmony_ci const GlslSource &cshader = context.getSourceCollection().get("comp"); 2109e5c31af7Sopenharmony_ci 2110e5c31af7Sopenharmony_ci unsigned totalIterations = 0; 2111e5c31af7Sopenharmony_ci unsigned failedIterations = 0; 2112e5c31af7Sopenharmony_ci 2113e5c31af7Sopenharmony_ci const deUint32 subgroupSize = getSubgroupSize(context); 2114e5c31af7Sopenharmony_ci 2115e5c31af7Sopenharmony_ci const deUint32 numWorkgroups[3] = {4, 2, 2}; 2116e5c31af7Sopenharmony_ci 2117e5c31af7Sopenharmony_ci const deUint32 localSizesToTestCount = 15; 2118e5c31af7Sopenharmony_ci deUint32 localSizesToTest[localSizesToTestCount][3] = 2119e5c31af7Sopenharmony_ci { 2120e5c31af7Sopenharmony_ci {1, 1, 1}, 2121e5c31af7Sopenharmony_ci {32, 4, 1}, 2122e5c31af7Sopenharmony_ci {32, 1, 4}, 2123e5c31af7Sopenharmony_ci {1, 32, 4}, 2124e5c31af7Sopenharmony_ci {1, 4, 32}, 2125e5c31af7Sopenharmony_ci {4, 1, 32}, 2126e5c31af7Sopenharmony_ci {4, 32, 1}, 2127e5c31af7Sopenharmony_ci {subgroupSize, 1, 1}, 2128e5c31af7Sopenharmony_ci {1, subgroupSize, 1}, 2129e5c31af7Sopenharmony_ci {1, 1, subgroupSize}, 2130e5c31af7Sopenharmony_ci {3, 5, 7}, 2131e5c31af7Sopenharmony_ci {128, 1, 1}, 2132e5c31af7Sopenharmony_ci {1, 128, 1}, 2133e5c31af7Sopenharmony_ci {1, 1, 64}, 2134e5c31af7Sopenharmony_ci {1, 1, 1} // Isn't used, just here to make double buffering checks easier 2135e5c31af7Sopenharmony_ci }; 2136e5c31af7Sopenharmony_ci 2137e5c31af7Sopenharmony_ci 2138e5c31af7Sopenharmony_ci de::MovePtr<glu::ShaderProgram> lastPipeline( 2139e5c31af7Sopenharmony_ci makeComputePipeline(context, cshader, 2140e5c31af7Sopenharmony_ci localSizesToTest[0][0], localSizesToTest[0][1], localSizesToTest[0][2])); 2141e5c31af7Sopenharmony_ci 2142e5c31af7Sopenharmony_ci for (deUint32 index = 0; index < (localSizesToTestCount - 1); index++) 2143e5c31af7Sopenharmony_ci { 2144e5c31af7Sopenharmony_ci const deUint32 nextX = localSizesToTest[index + 1][0]; 2145e5c31af7Sopenharmony_ci const deUint32 nextY = localSizesToTest[index + 1][1]; 2146e5c31af7Sopenharmony_ci const deUint32 nextZ = localSizesToTest[index + 1][2]; 2147e5c31af7Sopenharmony_ci 2148e5c31af7Sopenharmony_ci // we are running one test 2149e5c31af7Sopenharmony_ci totalIterations++; 2150e5c31af7Sopenharmony_ci 2151e5c31af7Sopenharmony_ci if (!lastPipeline->isOk()) 2152e5c31af7Sopenharmony_ci { 2153e5c31af7Sopenharmony_ci return tcu::TestStatus::fail("compute shaders build failed"); 2154e5c31af7Sopenharmony_ci } 2155e5c31af7Sopenharmony_ci 2156e5c31af7Sopenharmony_ci gl.useProgram(lastPipeline->getProgram()); 2157e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram"); 2158e5c31af7Sopenharmony_ci 2159e5c31af7Sopenharmony_ci gl.dispatchCompute(numWorkgroups[0], numWorkgroups[1], numWorkgroups[2]); 2160e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glDispatchCompute"); 2161e5c31af7Sopenharmony_ci 2162e5c31af7Sopenharmony_ci de::MovePtr<glu::ShaderProgram> nextPipeline( 2163e5c31af7Sopenharmony_ci makeComputePipeline(context, cshader, nextX, nextY, nextZ)); 2164e5c31af7Sopenharmony_ci 2165e5c31af7Sopenharmony_ci std::vector<const void*> datas; 2166e5c31af7Sopenharmony_ci 2167e5c31af7Sopenharmony_ci { 2168e5c31af7Sopenharmony_ci glw::GLvoid * resultData = resultBuffer.mapBufferPtr(); 2169e5c31af7Sopenharmony_ci 2170e5c31af7Sopenharmony_ci // we always have our result data first 2171e5c31af7Sopenharmony_ci datas.push_back(resultData); 2172e5c31af7Sopenharmony_ci } 2173e5c31af7Sopenharmony_ci 2174e5c31af7Sopenharmony_ci for (deUint32 i = 0; i < inputsCount; i++) 2175e5c31af7Sopenharmony_ci { 2176e5c31af7Sopenharmony_ci if (!inputBuffers[i]->isImage()) 2177e5c31af7Sopenharmony_ci { 2178e5c31af7Sopenharmony_ci glw::GLvoid *resultData = inputBuffers[i]->getAsBuffer()->mapBufferPtr(); 2179e5c31af7Sopenharmony_ci 2180e5c31af7Sopenharmony_ci // we always have our result data first 2181e5c31af7Sopenharmony_ci datas.push_back(resultData); 2182e5c31af7Sopenharmony_ci } 2183e5c31af7Sopenharmony_ci } 2184e5c31af7Sopenharmony_ci 2185e5c31af7Sopenharmony_ci if (!checkResult(datas, numWorkgroups, localSizesToTest[index], subgroupSize)) 2186e5c31af7Sopenharmony_ci { 2187e5c31af7Sopenharmony_ci failedIterations++; 2188e5c31af7Sopenharmony_ci } 2189e5c31af7Sopenharmony_ci 2190e5c31af7Sopenharmony_ci resultBuffer.unmapBufferPtr(); 2191e5c31af7Sopenharmony_ci for (deUint32 i = 0; i < inputsCount; i++) 2192e5c31af7Sopenharmony_ci { 2193e5c31af7Sopenharmony_ci if (!inputBuffers[i]->isImage()) 2194e5c31af7Sopenharmony_ci { 2195e5c31af7Sopenharmony_ci inputBuffers[i]->getAsBuffer()->unmapBufferPtr(); 2196e5c31af7Sopenharmony_ci } 2197e5c31af7Sopenharmony_ci } 2198e5c31af7Sopenharmony_ci 2199e5c31af7Sopenharmony_ci lastPipeline = nextPipeline; 2200e5c31af7Sopenharmony_ci } 2201e5c31af7Sopenharmony_ci 2202e5c31af7Sopenharmony_ci if (0 < failedIterations) 2203e5c31af7Sopenharmony_ci { 2204e5c31af7Sopenharmony_ci log << tcu::TestLog::Message << (totalIterations - failedIterations) << " / " 2205e5c31af7Sopenharmony_ci << totalIterations << " values passed" << tcu::TestLog::EndMessage; 2206e5c31af7Sopenharmony_ci return tcu::TestStatus::fail("Failed!"); 2207e5c31af7Sopenharmony_ci } else 2208e5c31af7Sopenharmony_ci { 2209e5c31af7Sopenharmony_ci log << tcu::TestLog::Message << (totalIterations - failedIterations) << " / " 2210e5c31af7Sopenharmony_ci << totalIterations << " values passed" << tcu::TestLog::EndMessage; 2211e5c31af7Sopenharmony_ci } 2212e5c31af7Sopenharmony_ci 2213e5c31af7Sopenharmony_ci return tcu::TestStatus::pass("OK"); 2214e5c31af7Sopenharmony_ci} 2215