148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/*------------------------------------------------------------------------- 248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * OpenGL Conformance Test Suite 348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * ----------------------------- 448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * Copyright (c) 2014-2016 The Khronos Group Inc. 648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * Licensed under the Apache License, Version 2.0 (the "License"); 848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * you may not use this file except in compliance with the License. 948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * You may obtain a copy of the License at 1048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * http://www.apache.org/licenses/LICENSE-2.0 1248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * Unless required by applicable law or agreed to in writing, software 1448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * distributed under the License is distributed on an "AS IS" BASIS, 1548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * See the License for the specific language governing permissions and 1748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * limitations under the License. 1848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1984322c9402f810da3cd80b52e9f9ef72150a9004Alexander Galazin */ /*! 2048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * \file 2148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * \brief 2284322c9402f810da3cd80b52e9f9ef72150a9004Alexander Galazin */ /*-------------------------------------------------------------------*/ 2348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 2448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#include "gl4cComputeShaderTests.hpp" 2548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#include "glwEnums.hpp" 2648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#include "glwFunctions.hpp" 2748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#include "tcuMatrix.hpp" 2848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#include "tcuMatrixUtil.hpp" 2948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#include "tcuRenderTarget.hpp" 3048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#include <cmath> 3148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#include <cstdarg> 3248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#include <sstream> 3348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 3448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosnamespace gl4cts 3548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 3648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 3748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosusing namespace glw; 3848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosusing tcu::Vec2; 3948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosusing tcu::Vec3; 4048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosusing tcu::Vec4; 4148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosusing tcu::UVec4; 4248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosusing tcu::UVec3; 4348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosusing tcu::Mat4; 4448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 4548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosnamespace 4648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 4748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 4848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulostypedef Vec3 vec2; 4948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulostypedef Vec3 vec3; 5048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulostypedef Vec4 vec4; 5148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulostypedef UVec3 uvec3; 5248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulostypedef UVec4 uvec4; 5348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulostypedef Mat4 mat4; 5448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 5548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosconst char* const kGLSLVer = "#version 430 core\n"; 5648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 5748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosclass ComputeShaderBase : public deqp::SubcaseBase 5848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 5948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 6048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulospublic: 6148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual ~ComputeShaderBase() 6248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 6348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 6448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 6548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos ComputeShaderBase() 6648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos : renderTarget(m_context.getRenderContext().getRenderTarget()), pixelFormat(renderTarget.getPixelFormat()) 6748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 6848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos float epsilon_zero = 1.f / (1 << 13); 6948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (pixelFormat.redBits != 0 && pixelFormat.greenBits != 0 && pixelFormat.blueBits != 0 && 7048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos pixelFormat.alphaBits != 0) 7148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 7248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos g_color_eps = vec4(1.f / ((float)(1 << pixelFormat.redBits) - 1.0f), 7348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1.f / ((float)(1 << pixelFormat.greenBits) - 1.0f), 7448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1.f / ((float)(1 << pixelFormat.blueBits) - 1.0f), 7548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1.f / ((float)(1 << pixelFormat.alphaBits) - 1.0f)) + 7648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos vec4(epsilon_zero); 7748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 7848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else if (pixelFormat.redBits != 0 && pixelFormat.greenBits != 0 && pixelFormat.blueBits != 0) 7948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 8048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos g_color_eps = vec4(1.f / ((float)(1 << pixelFormat.redBits) - 1.0f), 8148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1.f / ((float)(1 << pixelFormat.greenBits) - 1.0f), 8248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1.f / ((float)(1 << pixelFormat.blueBits) - 1.0f), 1.f) + 8348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos vec4(epsilon_zero); 8448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 8548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else 8648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 8748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos g_color_eps = vec4(epsilon_zero); 8848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 8948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 9048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 9148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const tcu::RenderTarget& renderTarget; 9248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const tcu::PixelFormat& pixelFormat; 9348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos vec4 g_color_eps; 9448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 9548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos uvec3 IndexTo3DCoord(GLuint idx, GLuint max_x, GLuint max_y) 9648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 9748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLuint x = idx % max_x; 9848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos idx /= max_x; 9948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLuint y = idx % max_y; 10048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos idx /= max_y; 10148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLuint z = idx; 10248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return uvec3(x, y, z); 10348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 10448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 10548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos bool CheckProgram(GLuint program, bool* compile_error = NULL) 10648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 10748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLint compile_status = GL_TRUE; 10848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLint status = GL_TRUE; 10948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetProgramiv(program, GL_LINK_STATUS, &status); 11048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 11148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (status == GL_FALSE) 11248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 11348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLint attached_shaders; 11448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetProgramiv(program, GL_ATTACHED_SHADERS, &attached_shaders); 11548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 11648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (attached_shaders > 0) 11748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 11848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::vector<GLuint> shaders(attached_shaders); 11948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetAttachedShaders(program, attached_shaders, NULL, &shaders[0]); 12048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 12148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLint i = 0; i < attached_shaders; ++i) 12248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 12348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLenum type; 12448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetShaderiv(shaders[i], GL_SHADER_TYPE, reinterpret_cast<GLint*>(&type)); 12548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos switch (type) 12648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 12748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case GL_VERTEX_SHADER: 128910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() 129910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << tcu::TestLog::Message << "*** Vertex Shader ***" << tcu::TestLog::EndMessage; 13048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 13148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case GL_TESS_CONTROL_SHADER: 132910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() 133910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << tcu::TestLog::Message << "*** Tessellation Control Shader ***" 134910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << tcu::TestLog::EndMessage; 13548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 13648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case GL_TESS_EVALUATION_SHADER: 137910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() 138910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << tcu::TestLog::Message << "*** Tessellation Evaluation Shader ***" 139910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << tcu::TestLog::EndMessage; 14048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 14148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case GL_GEOMETRY_SHADER: 142910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() 143910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << tcu::TestLog::Message << "*** Geometry Shader ***" << tcu::TestLog::EndMessage; 14448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 14548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case GL_FRAGMENT_SHADER: 146910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() 147910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << tcu::TestLog::Message << "*** Fragment Shader ***" << tcu::TestLog::EndMessage; 14848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 14948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case GL_COMPUTE_SHADER: 150910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() 151910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << tcu::TestLog::Message << "*** Compute Shader ***" << tcu::TestLog::EndMessage; 15248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 15348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos default: 154910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() 155910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << tcu::TestLog::Message << "*** Unknown Shader ***" << tcu::TestLog::EndMessage; 15648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 15748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 15848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 15948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLint res; 16048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetShaderiv(shaders[i], GL_COMPILE_STATUS, &res); 16148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (res != GL_TRUE) 16248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos compile_status = res; 16348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 16448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLint length; 16548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetShaderiv(shaders[i], GL_SHADER_SOURCE_LENGTH, &length); 16648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (length > 0) 16748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 16848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::vector<GLchar> source(length); 16948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetShaderSource(shaders[i], length, NULL, &source[0]); 170910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() 171910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << tcu::TestLog::Message << &source[0] << tcu::TestLog::EndMessage; 17248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 17348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 17448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetShaderiv(shaders[i], GL_INFO_LOG_LENGTH, &length); 17548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (length > 0) 17648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 17748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::vector<GLchar> log(length); 17848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetShaderInfoLog(shaders[i], length, NULL, &log[0]); 179910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() 180910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << tcu::TestLog::Message << &log[0] << tcu::TestLog::EndMessage; 18148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 18248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 18348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 18448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 18548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLint length; 18648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetProgramiv(program, GL_INFO_LOG_LENGTH, &length); 18748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (length > 0) 18848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 18948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::vector<GLchar> log(length); 19048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetProgramInfoLog(program, length, NULL, &log[0]); 191910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() << tcu::TestLog::Message << &log[0] << tcu::TestLog::EndMessage; 19248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 19348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 19448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 19548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (compile_error) 19648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *compile_error = (compile_status == GL_TRUE ? false : true); 19748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (compile_status != GL_TRUE) 19848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return false; 19948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return status == GL_TRUE ? true : false; 20048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 20148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 20248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint CreateComputeProgram(const std::string& cs) 20348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 20448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLuint p = glCreateProgram(); 20548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 20648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!cs.empty()) 20748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 20848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLuint sh = glCreateShader(GL_COMPUTE_SHADER); 20948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glAttachShader(p, sh); 21048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteShader(sh); 21148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* const src[2] = { kGLSLVer, cs.c_str() }; 21248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glShaderSource(sh, 2, src, NULL); 21348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glCompileShader(sh); 21448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 21548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 21648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return p; 21748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 21848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 21948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint CreateProgram(const std::string& vs, const std::string& fs) 22048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 22148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLuint p = glCreateProgram(); 22248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 22348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!vs.empty()) 22448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 22548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLuint sh = glCreateShader(GL_VERTEX_SHADER); 22648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glAttachShader(p, sh); 22748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteShader(sh); 22848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* const src[2] = { kGLSLVer, vs.c_str() }; 22948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glShaderSource(sh, 2, src, NULL); 23048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glCompileShader(sh); 23148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 23248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!fs.empty()) 23348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 23448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLuint sh = glCreateShader(GL_FRAGMENT_SHADER); 23548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glAttachShader(p, sh); 23648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteShader(sh); 23748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* const src[2] = { kGLSLVer, fs.c_str() }; 23848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glShaderSource(sh, 2, src, NULL); 23948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glCompileShader(sh); 24048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 24148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 24248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return p; 24348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 24448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 24548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint BuildShaderProgram(GLenum type, const std::string& source) 24648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 24748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* const src[2] = { kGLSLVer, source.c_str() }; 24848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return glCreateShaderProgramv(type, 2, src); 24948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 25048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 25148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLfloat distance(GLfloat p0, GLfloat p1) 25248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 25348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return de::abs(p0 - p1); 25448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 25548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 25648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos inline bool ColorEqual(const vec4& c0, const vec4& c1, const vec4& epsilon) 25748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 25848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (distance(c0.x(), c1.x()) > epsilon.x()) 25948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return false; 26048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (distance(c0.y(), c1.y()) > epsilon.y()) 26148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return false; 26248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (distance(c0.z(), c1.z()) > epsilon.z()) 26348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return false; 26448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (distance(c0.w(), c1.w()) > epsilon.w()) 26548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return false; 26648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return true; 26748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 26848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 26948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos inline bool ColorEqual(const vec3& c0, const vec3& c1, const vec4& epsilon) 27048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 27148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (distance(c0.x(), c1.x()) > epsilon.x()) 27248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return false; 27348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (distance(c0.y(), c1.y()) > epsilon.y()) 27448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return false; 27548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (distance(c0.z(), c1.z()) > epsilon.z()) 27648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return false; 27748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return true; 27848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 27948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 28048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos bool ValidateReadBuffer(int x, int y, int w, int h, const vec4& expected) 28148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 28248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::vector<vec4> display(w * h); 28348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glReadPixels(x, y, w, h, GL_RGBA, GL_FLOAT, &display[0]); 28448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 28548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (int j = 0; j < h; ++j) 28648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 28748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (int i = 0; i < w; ++i) 28848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 28948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!ColorEqual(display[j * w + i], expected, g_color_eps)) 29048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 291910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() 292910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << tcu::TestLog::Message << "Color at (" << (x + i) << ", " << (y + j) << ") is [" 293910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << display[j * w + i].x() << ", " << display[j * w + i].y() << ", " << display[j * w + i].z() 294910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << ", " << display[j * w + i].w() << "] should be [" << expected.x() << ", " << expected.y() 295910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << ", " << expected.z() << ", " << expected.w() << "]." << tcu::TestLog::EndMessage; 29648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return false; 29748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 29848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 29948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 30048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 30148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return true; 30248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 30348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 30448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos bool ValidateReadBufferCenteredQuad(int width, int height, const vec3& expected) 30548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 30648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos bool result = true; 30748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::vector<vec3> fb(width * height); 30848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glReadPixels(0, 0, width, height, GL_RGB, GL_FLOAT, &fb[0]); 30948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 31048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos int startx = int(((float)width * 0.1f) + 1); 31148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos int starty = int(((float)height * 0.1f) + 1); 31248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos int endx = int((float)width - 2 * (((float)width * 0.1f) + 1) - 1); 31348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos int endy = int((float)height - 2 * (((float)height * 0.1f) + 1) - 1); 31448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 31548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (int y = starty; y < endy; ++y) 31648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 31748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (int x = startx; x < endx; ++x) 31848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 31948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const int idx = y * width + x; 32048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!ColorEqual(fb[idx], expected, g_color_eps)) 32148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 32248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return false; 32348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 32448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 32548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 32648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 32748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!ColorEqual(fb[2 * width + 2], vec3(0), g_color_eps)) 32848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 32948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = false; 33048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 33148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!ColorEqual(fb[2 * width + (width - 3)], vec3(0), g_color_eps)) 33248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 33348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = false; 33448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 33548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!ColorEqual(fb[(height - 3) * width + (width - 3)], vec3(0), g_color_eps)) 33648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 33748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = false; 33848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 33948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!ColorEqual(fb[(height - 3) * width + 2], vec3(0), g_color_eps)) 34048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 34148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = false; 34248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 34348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 34448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return result; 34548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 34648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 34748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos int getWindowWidth() 34848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 34948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return renderTarget.getWidth(); 35048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 35148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 35248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos int getWindowHeight() 35348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 35448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return renderTarget.getHeight(); 35548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 35648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 35748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos bool ValidateWindow4Quads(const vec3& lb, const vec3& rb, const vec3& rt, const vec3& lt) 35848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 35948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos int width = 100; 36048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos int height = 100; 36148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::vector<vec3> fb(width * height); 36248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glReadPixels(0, 0, width, height, GL_RGB, GL_FLOAT, &fb[0]); 36348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 36448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos bool status = true; 36548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 36648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos // left-bottom quad 36748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (int y = 10; y < height / 2 - 10; ++y) 36848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 36948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (int x = 10; x < width / 2 - 10; ++x) 37048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 37148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const int idx = y * width + x; 37248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!ColorEqual(fb[idx], lb, g_color_eps)) 37348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 374910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() 375910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << tcu::TestLog::Message << "First bad color (" << x << ", " << y << "): " << fb[idx].x() << " " 376910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << fb[idx].y() << " " << fb[idx].z() << tcu::TestLog::EndMessage; 37748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos status = false; 37848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 37948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 38048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 38148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos // right-bottom quad 38248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (int y = 10; y < height / 2 - 10; ++y) 38348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 38448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (int x = width / 2 + 10; x < width - 10; ++x) 38548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 38648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const int idx = y * width + x; 38748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!ColorEqual(fb[idx], rb, g_color_eps)) 38848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 389910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() 390910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << tcu::TestLog::Message << "Bad color at (" << x << ", " << y << "): " << fb[idx].x() << " " 391910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << fb[idx].y() << " " << fb[idx].z() << tcu::TestLog::EndMessage; 39248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos status = false; 39348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 39448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 39548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 39648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos // right-top quad 39748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (int y = height / 2 + 10; y < height - 10; ++y) 39848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 39948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (int x = width / 2 + 10; x < width - 10; ++x) 40048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 40148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const int idx = y * width + x; 40248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!ColorEqual(fb[idx], rt, g_color_eps)) 40348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 404910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() 405910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << tcu::TestLog::Message << "Bad color at (" << x << ", " << y << "): " << fb[idx].x() << " " 406910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << fb[idx].y() << " " << fb[idx].z() << tcu::TestLog::EndMessage; 40748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos status = false; 40848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 40948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 41048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 41148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos // left-top quad 41248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (int y = height / 2 + 10; y < height - 10; ++y) 41348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 41448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (int x = 10; x < width / 2 - 10; ++x) 41548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 41648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const int idx = y * width + x; 41748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!ColorEqual(fb[idx], lt, g_color_eps)) 41848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 419910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() 420910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << tcu::TestLog::Message << "Bad color at (" << x << ", " << y << "): " << fb[idx].x() << " " 421910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << fb[idx].y() << " " << fb[idx].z() << tcu::TestLog::EndMessage; 42248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos status = false; 42348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 42448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 42548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 42648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos // middle horizontal line should be black 42748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (int y = height / 2 - 2; y < height / 2 + 2; ++y) 42848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 42948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (int x = 0; x < width; ++x) 43048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 43148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const int idx = y * width + x; 43248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!ColorEqual(fb[idx], vec3(0), g_color_eps)) 43348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 434910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() 435910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << tcu::TestLog::Message << "Bad color at (" << x << ", " << y << "): " << fb[idx].x() << " " 436910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << fb[idx].y() << " " << fb[idx].z() << tcu::TestLog::EndMessage; 43748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos status = false; 43848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 43948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 44048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 44148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos // middle vertical line should be black 44248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (int y = 0; y < height; ++y) 44348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 44448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (int x = width / 2 - 2; x < width / 2 + 2; ++x) 44548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 44648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const int idx = y * width + x; 44748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!ColorEqual(fb[idx], vec3(0), g_color_eps)) 44848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 449910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() 450910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << tcu::TestLog::Message << "Bad color at (" << x << ", " << y << "): " << fb[idx].x() << " " 451910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << fb[idx].y() << " " << fb[idx].z() << tcu::TestLog::EndMessage; 45248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos status = false; 45348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 45448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 45548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 45648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 45748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return status; 45848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 45948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 46048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos bool IsEqual(vec4 a, vec4 b) 46148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 46248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return (a.x() == b.x()) && (a.y() == b.y()) && (a.z() == b.z()) && (a.w() == b.w()); 46348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 46448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 46548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos bool IsEqual(uvec4 a, uvec4 b) 46648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 46748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return (a.x() == b.x()) && (a.y() == b.y()) && (a.z() == b.z()) && (a.w() == b.w()); 46848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 46948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}; 47048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 47148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosclass SimpleCompute : public ComputeShaderBase 47248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 47348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 47448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Title() 47548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 47648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return "Simplest possible Compute Shader"; 47748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 47848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 47948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Purpose() 48048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 48148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return "1. Verify that CS can be created, compiled and linked.\n" 48248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "2. Verify that local work size can be queried with GetProgramiv command.\n" 48348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "3. Verify that CS can be dispatched with DispatchCompute command.\n" 48448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "4. Verify that CS can write to SSBO."; 48548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 48648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 48748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Method() 48848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 48948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return "Create and dispatch CS. Verify SSBO content."; 49048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 49148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 49248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string PassCriteria() 49348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 49448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return "Everything works as expected."; 49548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 49648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 49748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_program; 49848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_buffer; 49948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 50048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Setup() 50148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 50248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 50348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* const glsl_cs = 50448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos NL "layout(local_size_x = 1, local_size_y = 1) in;" NL "layout(std430) buffer Output {" NL " vec4 data;" NL 50548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "} g_out;" NL "void main() {" NL " g_out.data = vec4(1.0, 2.0, 3.0, 4.0);" NL "}"; 50648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_program = CreateComputeProgram(glsl_cs); 50748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glLinkProgram(m_program); 50848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!CheckProgram(m_program)) 50948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 51048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 51148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLint v[3]; 51248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetProgramiv(m_program, GL_COMPUTE_WORK_GROUP_SIZE, v); 51348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (v[0] != 1 || v[1] != 1 || v[2] != 1) 51448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 515910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() 516910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << tcu::TestLog::Message << "Got " << v[0] << ", " << v[1] << ", " << v[2] 517910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << ", expected: 1, 1, 1 in GL_COMPUTE_WORK_GROUP_SIZE check" << tcu::TestLog::EndMessage; 51848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 51948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 52048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 52148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGenBuffers(1, &m_buffer); 52248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_buffer); 52348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(vec4), NULL, GL_DYNAMIC_DRAW); 52448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0); 52548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 52648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 52748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 52848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 52948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Run() 53048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 53148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUseProgram(m_program); 53248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDispatchCompute(1, 1, 1); 53348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 53448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos vec4* data; 53548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_buffer); 53648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT); 53748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos data = static_cast<vec4*>(glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, sizeof(vec4), GL_MAP_READ_BIT)); 53848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos long error = NO_ERROR; 53948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!IsEqual(data[0], vec4(1.0f, 2.0f, 3.0f, 4.0f))) 54048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 54148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos error = ERROR; 54248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 54348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUnmapBuffer(GL_SHADER_STORAGE_BUFFER); 54448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0); 54548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return error; 54648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 54748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 54848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Cleanup() 54948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 55048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUseProgram(0); 55148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteProgram(m_program); 55248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteBuffers(1, &m_buffer); 55348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 55448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 55548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}; 55648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 55748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosclass BasicOneWorkGroup : public ComputeShaderBase 55848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 55948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 56048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Title() 56148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 56248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return "One work group with various local sizes"; 56348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 56448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 56548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Purpose() 56648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 56748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "1. Verify that declared local work size has correct effect." NL 56848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "2. Verify that the number of shader invocations is correct." NL 56948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "3. Verify that the built-in variables: gl_WorkGroupSize, gl_WorkGroupID, gl_GlobalInvocationID," NL 57048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " gl_LocalInvocationID and gl_LocalInvocationIndex has correct values." NL 57148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "4. Verify that DispatchCompute and DispatchComputeIndirect commands work as expected."; 57248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 57348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 57448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Method() 57548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 57648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "1. Create several CS with various local sizes." NL 57748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "2. Dispatch each CS with DispatchCompute and DispatchComputeIndirect commands." NL 57848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "3. Verify SSBO content."; 57948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 58048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 58148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string PassCriteria() 58248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 58348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return "Everything works as expected."; 58448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 58548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 58648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_program; 58748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_storage_buffer; 58848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_dispatch_buffer; 58948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 59048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::string GenSource(int x, int y, int z, GLuint binding) 59148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 59248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::stringstream ss; 59348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos ss << NL "layout(local_size_x = " << x << ", local_size_y = " << y << ", local_size_z = " << z 59448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << ") in;" NL "layout(std430, binding = " << binding 59548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << ") buffer Output {" NL " uvec4 local_id[];" NL "} g_out;" NL "void main() {" NL 59648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " if (gl_WorkGroupSize == uvec3(" 59748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << x << ", " << y << ", " << z 59848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << ") && gl_WorkGroupID == uvec3(0) &&" NL " gl_GlobalInvocationID == gl_LocalInvocationID) {" NL 59948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " g_out.local_id[gl_LocalInvocationIndex] = uvec4(gl_LocalInvocationID, 0);" NL " } else {" NL 60048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " g_out.local_id[gl_LocalInvocationIndex] = uvec4(0xffff);" NL " }" NL "}"; 60148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ss.str(); 60248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 60348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 60448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos bool RunIteration(int local_size_x, int local_size_y, int local_size_z, GLuint binding, bool dispatch_indirect) 60548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 60648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_program != 0) 60748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteProgram(m_program); 60848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_program = CreateComputeProgram(GenSource(local_size_x, local_size_y, local_size_z, binding)); 60948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glLinkProgram(m_program); 61048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!CheckProgram(m_program)) 61148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return false; 61248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 61348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLint v[3]; 61448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetProgramiv(m_program, GL_COMPUTE_WORK_GROUP_SIZE, v); 61548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (v[0] != local_size_x || v[1] != local_size_y || v[2] != local_size_z) 61648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 617910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() 618910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << tcu::TestLog::Message << "GL_COMPUTE_LOCAL_WORK_SIZE is (" << v[0] << " " << v[1] << " " << v[2] 619910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << ") should be (" << local_size_x << " " << local_size_y << " " << local_size_z << ")" 620910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << tcu::TestLog::EndMessage; 62148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return false; 62248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 62348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 62448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const int kSize = local_size_x * local_size_y * local_size_z; 62548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 62648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_storage_buffer == 0) 62748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGenBuffers(1, &m_storage_buffer); 62848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBufferBase(GL_SHADER_STORAGE_BUFFER, binding, m_storage_buffer); 62948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(uvec4) * kSize, NULL, GL_DYNAMIC_DRAW); 63048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0); 63148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 63248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUseProgram(m_program); 63348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (dispatch_indirect) 63448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 63548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLuint num_groups[3] = { 1, 1, 1 }; 63648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_dispatch_buffer == 0) 63748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGenBuffers(1, &m_dispatch_buffer); 63848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBuffer(GL_DISPATCH_INDIRECT_BUFFER, m_dispatch_buffer); 63948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBufferData(GL_DISPATCH_INDIRECT_BUFFER, sizeof(num_groups), num_groups, GL_STATIC_DRAW); 64048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDispatchComputeIndirect(0); 64148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 64248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else 64348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 64448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDispatchCompute(1, 1, 1); 64548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 64648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 64748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos uvec4* data; 64848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer); 64948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT); 65048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos data = 65148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static_cast<uvec4*>(glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, kSize * sizeof(uvec4), GL_MAP_READ_BIT)); 65248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 65348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos bool ret = true; 65448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 65548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (int z = 0; z < local_size_z; ++z) 65648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 65748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (int y = 0; y < local_size_y; ++y) 65848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 65948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (int x = 0; x < local_size_x; ++x) 66048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 66148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const int index = z * local_size_x * local_size_y + y * local_size_x + x; 66248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!IsEqual(data[index], uvec4(x, y, z, 0))) 66348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 664910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() 665910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << tcu::TestLog::Message << "Invalid data at offset " << index << tcu::TestLog::EndMessage; 66648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos ret = false; 66748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 66848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 66948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 67048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 67148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUnmapBuffer(GL_SHADER_STORAGE_BUFFER); 67248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0); 67348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ret; 67448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 67548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 67648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Setup() 67748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 67848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_program = 0; 67948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_storage_buffer = 0; 68048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_dispatch_buffer = 0; 68148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 68248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 68348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 68448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Run() 68548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 68648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!RunIteration(16, 1, 1, 0, true)) 68748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 68848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!RunIteration(8, 8, 1, 1, false)) 68948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 69048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!RunIteration(4, 4, 4, 2, true)) 69148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 69248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!RunIteration(1, 2, 3, 3, false)) 69348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 69448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!RunIteration(1024, 1, 1, 3, true)) 69548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 69648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!RunIteration(16, 8, 8, 3, false)) 69748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 69848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!RunIteration(32, 1, 32, 7, true)) 69948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 70048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 70148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 70248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 70348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Cleanup() 70448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 70548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUseProgram(0); 70648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteProgram(m_program); 70748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteBuffers(1, &m_storage_buffer); 70848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteBuffers(1, &m_dispatch_buffer); 70948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 71048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 71148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}; 71248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 71348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosclass BasicResourceUBO : public ComputeShaderBase 71448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 71548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 71648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Title() 71748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 71848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return "Compute Shader resources - UBOs"; 71948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 72048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 72148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Purpose() 72248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 72348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return "Verify that CS is able to read data from UBOs and write it to SSBO."; 72448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 72548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 72648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Method() 72748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 72848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "1. Create CS which uses array of UBOs." NL 72948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "2. Dispatch CS with DispatchCompute and DispatchComputeIndirect commands." NL 73048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "3. Read data from each UBO and write it to SSBO." NL "4. Verify SSBO content." NL 73148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "5. Repeat for different buffer and CS work sizes."; 73248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 73348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 73448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string PassCriteria() 73548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 73648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return "Everything works as expected."; 73748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 73848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 73948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_program; 74048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_storage_buffer; 74148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_uniform_buffer[12]; 74248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_dispatch_buffer; 74348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 74448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::string GenSource(const uvec3& local_size, const uvec3& num_groups) 74548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 74648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const uvec3 global_size = local_size * num_groups; 74748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::stringstream ss; 74848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos ss << NL "layout(local_size_x = " << local_size.x() << ", local_size_y = " << local_size.y() 74948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << ", local_size_z = " << local_size.z() << ") in;" NL "const uvec3 kGlobalSize = uvec3(" << global_size.x() 75048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << ", " << global_size.y() << ", " << global_size.z() 75148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << ");" NL "layout(std140) uniform InputBuffer {" NL " vec4 data[" 75248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << global_size.x() * global_size.y() * global_size.z() 75348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << "];" NL "} g_in_buffer[12];" NL "layout(std430) buffer OutputBuffer {" NL " vec4 data0[" 75448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << global_size.x() * global_size.y() * global_size.z() << "];" NL " vec4 data1[" 75548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << global_size.x() * global_size.y() * global_size.z() << "];" NL " vec4 data2[" 75648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << global_size.x() * global_size.y() * global_size.z() << "];" NL " vec4 data3[" 75748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << global_size.x() * global_size.y() * global_size.z() << "];" NL " vec4 data4[" 75848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << global_size.x() * global_size.y() * global_size.z() << "];" NL " vec4 data5[" 75948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << global_size.x() * global_size.y() * global_size.z() << "];" NL " vec4 data6[" 76048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << global_size.x() * global_size.y() * global_size.z() << "];" NL " vec4 data7[" 76148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << global_size.x() * global_size.y() * global_size.z() << "];" NL " vec4 data8[" 76248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << global_size.x() * global_size.y() * global_size.z() << "];" NL " vec4 data9[" 76348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << global_size.x() * global_size.y() * global_size.z() << "];" NL " vec4 data10[" 76448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << global_size.x() * global_size.y() * global_size.z() << "];" NL " vec4 data11[" 76548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << global_size.x() * global_size.y() * global_size.z() 76648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << "];" NL "} g_out_buffer;" NL "void main() {" NL " const uint global_index = gl_GlobalInvocationID.x +" NL 76748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " gl_GlobalInvocationID.y * kGlobalSize.x +" NL 76848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " gl_GlobalInvocationID.z * kGlobalSize.x * kGlobalSize.y;" NL 76948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " g_out_buffer.data0[global_index] = g_in_buffer[0].data[global_index];" NL 77048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " g_out_buffer.data1[global_index] = g_in_buffer[1].data[global_index];" NL 77148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " g_out_buffer.data2[global_index] = g_in_buffer[2].data[global_index];" NL 77248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " g_out_buffer.data3[global_index] = g_in_buffer[3].data[global_index];" NL 77348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " g_out_buffer.data4[global_index] = g_in_buffer[4].data[global_index];" NL 77448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " g_out_buffer.data5[global_index] = g_in_buffer[5].data[global_index];" NL 77548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " g_out_buffer.data6[global_index] = g_in_buffer[6].data[global_index];" NL 77648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " g_out_buffer.data7[global_index] = g_in_buffer[7].data[global_index];" NL 77748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " g_out_buffer.data8[global_index] = g_in_buffer[8].data[global_index];" NL 77848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " g_out_buffer.data9[global_index] = g_in_buffer[9].data[global_index];" NL 77948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " g_out_buffer.data10[global_index] = g_in_buffer[10].data[global_index];" NL 78048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " g_out_buffer.data11[global_index] = g_in_buffer[11].data[global_index];" NL "}"; 78148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ss.str(); 78248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 78348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 78448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos bool RunIteration(const uvec3& local_size, const uvec3& num_groups, bool dispatch_indirect) 78548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 78648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_program != 0) 78748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteProgram(m_program); 78848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_program = CreateComputeProgram(GenSource(local_size, num_groups)); 78948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glLinkProgram(m_program); 79048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!CheckProgram(m_program)) 79148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return false; 79248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 79348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLuint i = 0; i < 12; ++i) 79448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 79548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos char name[32]; 79648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos sprintf(name, "InputBuffer[%u]", i); 79748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLuint index = glGetUniformBlockIndex(m_program, name); 79848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUniformBlockBinding(m_program, index, i); 79948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLint p = 0; 80048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetActiveUniformBlockiv(m_program, index, GL_UNIFORM_BLOCK_REFERENCED_BY_COMPUTE_SHADER, &p); 80148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (p == GL_FALSE) 80248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 803910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() 804910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << tcu::TestLog::Message << "UNIFORM_BLOCK_REFERENCED_BY_COMPUTE_SHADER should be TRUE." 805910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << tcu::TestLog::EndMessage; 80648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return false; 80748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 80848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 80948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 81048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLuint kBufferSize = 81148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos local_size.x() * num_groups.x() * local_size.y() * num_groups.y() * local_size.z() * num_groups.z(); 81248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 81348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_storage_buffer == 0) 81448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGenBuffers(1, &m_storage_buffer); 81548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_storage_buffer); 81648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(vec4) * kBufferSize * 12, NULL, GL_DYNAMIC_DRAW); 81748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0); 81848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 81948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_uniform_buffer[0] == 0) 82048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGenBuffers(12, m_uniform_buffer); 82148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLuint i = 0; i < 12; ++i) 82248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 82348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::vector<vec4> data(kBufferSize); 82448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLuint j = 0; j < kBufferSize; ++j) 82548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 82648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos data[j] = vec4(static_cast<float>(i * kBufferSize + j)); 82748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 82848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBufferBase(GL_UNIFORM_BUFFER, i, m_uniform_buffer[i]); 82948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBufferData(GL_UNIFORM_BUFFER, sizeof(vec4) * kBufferSize, &data[0], GL_DYNAMIC_DRAW); 83048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 83148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBuffer(GL_UNIFORM_BUFFER, 0); 83248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 83348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUseProgram(m_program); 83448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (dispatch_indirect) 83548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 83648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_dispatch_buffer == 0) 83748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGenBuffers(1, &m_dispatch_buffer); 83848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBuffer(GL_DISPATCH_INDIRECT_BUFFER, m_dispatch_buffer); 83948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBufferData(GL_DISPATCH_INDIRECT_BUFFER, sizeof(num_groups), &num_groups[0], GL_STATIC_DRAW); 84048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDispatchComputeIndirect(0); 84148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 84248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else 84348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 84448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDispatchCompute(num_groups.x(), num_groups.y(), num_groups.z()); 84548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 84648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 84748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::vector<vec4> data(kBufferSize * 12); 84848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer); 84948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT); 85048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, sizeof(vec4) * kBufferSize * 12, &data[0]); 85148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 85248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLuint z = 0; z < local_size.z() * num_groups.z(); ++z) 85348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 85448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLuint y = 0; y < local_size.y() * num_groups.y(); ++y) 85548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 85648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLuint x = 0; x < local_size.x() * num_groups.x(); ++x) 85748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 85848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLuint index = z * local_size.x() * num_groups.x() * local_size.y() * num_groups.y() + 85948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos y * local_size.x() * num_groups.x() + x; 86048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (int i = 0; i < 1; ++i) 86148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 86248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!IsEqual(data[index * 12 + i], vec4(static_cast<float>(index * 12 + i)))) 86348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 864910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() << tcu::TestLog::Message << "Incorrect data at offset " 865910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << index * 12 + i << "." << tcu::TestLog::EndMessage; 86648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return false; 86748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 86848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 86948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 87048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 87148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 87248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return true; 87348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 87448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 87548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Setup() 87648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 87748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_program = 0; 87848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_storage_buffer = 0; 87948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos memset(m_uniform_buffer, 0, sizeof(m_uniform_buffer)); 88048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_dispatch_buffer = 0; 88148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 88248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 88348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 88448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Run() 88548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 88648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!RunIteration(uvec3(64, 1, 1), uvec3(8, 1, 1), false)) 88748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 88848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!RunIteration(uvec3(2, 2, 2), uvec3(2, 2, 2), true)) 88948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 89048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!RunIteration(uvec3(2, 4, 2), uvec3(2, 4, 1), false)) 89148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 89248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 89348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 89448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 89548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Cleanup() 89648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 89748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUseProgram(0); 89848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteProgram(m_program); 89948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteBuffers(1, &m_storage_buffer); 90048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteBuffers(12, m_uniform_buffer); 90148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteBuffers(1, &m_dispatch_buffer); 90248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 90348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 90448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}; 90548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 90648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosclass BasicResourceTexture : public ComputeShaderBase 90748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 90848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 90948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Title() 91048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 91148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "Compute Shader resources - Textures"; 91248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 91348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 91448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Purpose() 91548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 91648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "Verify that texture access works correctly in CS."; 91748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 91848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 91948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Method() 92048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 92148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "1. Create CS which uses all sampler types (sampler1D, sampler2D, sampler3D, sampler2DRect," NL 92248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " sampler1DArray, sampler2DArray, samplerBuffer, sampler2DMS, sampler2DMSArray)." NL 92348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "2. Dispatch CS with DispatchCompute and DispatchComputeIndirect commands." NL 92448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "3. Sample each texture and write sampled value to SSBO." NL "4. Verify SSBO content." NL 92548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "5. Repeat for different texture and CS work sizes."; 92648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 92748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 92848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string PassCriteria() 92948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 93048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "Everything works as expected."; 93148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 93248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 93348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_program; 93448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_storage_buffer; 93548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_texture[9]; 93648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_texture_buffer; 93748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_dispatch_buffer; 93848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 93948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::string GenSource(const uvec3& local_size, const uvec3& num_groups) 94048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 94148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const uvec3 global_size = local_size * num_groups; 94248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::stringstream ss; 94348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos ss << NL "layout(local_size_x = " << local_size.x() << ", local_size_y = " << local_size.y() 94448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << ", local_size_z = " << local_size.z() << ") in;" NL "const uvec3 kGlobalSize = uvec3(" << global_size.x() 94548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << ", " << global_size.y() << ", " << global_size.z() 94648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << ");" NL "uniform sampler1D g_sampler0;" NL "uniform sampler2D g_sampler1;" NL 94748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "uniform sampler3D g_sampler2;" NL "uniform sampler2DRect g_sampler3;" NL 94848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "uniform sampler1DArray g_sampler4;" NL "uniform sampler2DArray g_sampler5;" NL 94948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "uniform samplerBuffer g_sampler6;" NL "uniform sampler2DMS g_sampler7;" NL 95048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "uniform sampler2DMSArray g_sampler8;" NL "layout(std430) buffer OutputBuffer {" NL " vec4 data0[" 95148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << global_size.x() * global_size.y() * global_size.z() << "];" NL " vec4 data1[" 95248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << global_size.x() * global_size.y() * global_size.z() << "];" NL " vec4 data2[" 95348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << global_size.x() * global_size.y() * global_size.z() << "];" NL " vec4 data3[" 95448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << global_size.x() * global_size.y() * global_size.z() << "];" NL " vec4 data4[" 95548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << global_size.x() * global_size.y() * global_size.z() << "];" NL " vec4 data5[" 95648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << global_size.x() * global_size.y() * global_size.z() << "];" NL " vec4 data6[" 95748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << global_size.x() * global_size.y() * global_size.z() << "];" NL " vec4 data7[" 95848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << global_size.x() * global_size.y() * global_size.z() << "];" NL " vec4 data8[" 95948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << global_size.x() * global_size.y() * global_size.z() 96048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << "];" NL "} g_out_buffer;" NL "void main() {" NL " const uint global_index = gl_GlobalInvocationID.x +" NL 96148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " gl_GlobalInvocationID.y * kGlobalSize.x +" NL 96248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " gl_GlobalInvocationID.z * kGlobalSize.x * kGlobalSize.y;" NL 96348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " g_out_buffer.data0[global_index] = texelFetch(g_sampler0, int(gl_GlobalInvocationID), 0);" NL 96448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " g_out_buffer.data1[global_index] = texture(g_sampler1, vec2(gl_GlobalInvocationID) / " 96548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "vec2(kGlobalSize));" NL " g_out_buffer.data2[global_index] = textureProj(g_sampler2, " 96648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "vec4(vec3(gl_GlobalInvocationID) / vec3(kGlobalSize), 1.0));" NL 96748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " g_out_buffer.data3[global_index] = textureProjOffset(g_sampler3, vec3(vec2(gl_GlobalInvocationID), " 96848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "1.0), ivec2(0));" NL " g_out_buffer.data4[global_index] = textureLodOffset(g_sampler4, " 96948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "vec2(gl_GlobalInvocationID.x / kGlobalSize.x, gl_GlobalInvocationID.y), 0.0, " 97048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "0);" NL " g_out_buffer.data5[global_index] = texelFetchOffset(g_sampler5, " 97148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "ivec3(gl_GlobalInvocationID), 0, ivec2(0));" NL 97248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " g_out_buffer.data6[global_index] = texelFetch(g_sampler6, int(global_index));" NL 97348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " g_out_buffer.data7[global_index] = texelFetch(g_sampler7, ivec2(gl_GlobalInvocationID), 1);" NL 97448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " g_out_buffer.data8[global_index] = texelFetch(g_sampler8, ivec3(gl_GlobalInvocationID), 2);" NL "}"; 97548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ss.str(); 97648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 97748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 97848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos bool RunIteration(const uvec3& local_size, const uvec3& num_groups, bool dispatch_indirect) 97948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 98048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_program != 0) 98148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteProgram(m_program); 98248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_program = CreateComputeProgram(GenSource(local_size, num_groups)); 98348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glLinkProgram(m_program); 98448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!CheckProgram(m_program)) 98548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return false; 98648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 98748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUseProgram(m_program); 98848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (int i = 0; i < 9; ++i) 98948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 99048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos char name[32]; 99148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos sprintf(name, "g_sampler%d", i); 99248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUniform1i(glGetUniformLocation(m_program, name), i); 99348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 99448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUseProgram(0); 99548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 99648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLuint kBufferSize = 99748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos local_size.x() * num_groups.x() * local_size.y() * num_groups.y() * local_size.z() * num_groups.z(); 99848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLint kWidth = static_cast<GLint>(local_size.x() * num_groups.x()); 99948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLint kHeight = static_cast<GLint>(local_size.y() * num_groups.y()); 100048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLint kDepth = static_cast<GLint>(local_size.z() * num_groups.z()); 100148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 100248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::vector<vec4> buffer_data(kBufferSize * 9); 100348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_storage_buffer == 0) 100448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGenBuffers(1, &m_storage_buffer); 100548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_storage_buffer); 100648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(vec4) * kBufferSize * 9, &buffer_data[0], GL_DYNAMIC_DRAW); 100748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0); 100848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 100948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::vector<vec4> texture_data(kBufferSize, vec4(123.0f)); 101048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_texture[0] == 0) 101148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGenTextures(9, m_texture); 101248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_texture_buffer == 0) 101348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGenBuffers(1, &m_texture_buffer); 101448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 101548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glActiveTexture(GL_TEXTURE0); 101648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindTexture(GL_TEXTURE_1D, m_texture[0]); 101748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 101848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 101948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA32F, kWidth, 0, GL_RGBA, GL_FLOAT, &texture_data[0]); 102048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 102148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glActiveTexture(GL_TEXTURE1); 102248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindTexture(GL_TEXTURE_2D, m_texture[1]); 102348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 102448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 102548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, kWidth, kHeight, 0, GL_RGBA, GL_FLOAT, &texture_data[0]); 102648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 102748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glActiveTexture(GL_TEXTURE2); 102848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindTexture(GL_TEXTURE_3D, m_texture[2]); 102948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 103048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 103148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA32F, kWidth, kHeight, kDepth, 0, GL_RGBA, GL_FLOAT, &texture_data[0]); 103248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 103348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glActiveTexture(GL_TEXTURE3); 103448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindTexture(GL_TEXTURE_RECTANGLE, m_texture[3]); 103548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 103648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 103748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glTexImage2D(GL_TEXTURE_RECTANGLE, 0, GL_RGBA32F, kWidth, kHeight, 0, GL_RGBA, GL_FLOAT, &texture_data[0]); 103848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 103948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glActiveTexture(GL_TEXTURE4); 104048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindTexture(GL_TEXTURE_1D_ARRAY, m_texture[4]); 104148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glTexParameteri(GL_TEXTURE_1D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 104248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glTexParameteri(GL_TEXTURE_1D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 104348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glTexImage2D(GL_TEXTURE_1D_ARRAY, 0, GL_RGBA32F, kWidth, kHeight, 0, GL_RGBA, GL_FLOAT, &texture_data[0]); 104448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 104548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glActiveTexture(GL_TEXTURE5); 104648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindTexture(GL_TEXTURE_2D_ARRAY, m_texture[5]); 104748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 104848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 104948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA32F, kWidth, kHeight, kDepth, 0, GL_RGBA, GL_FLOAT, 105048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos &texture_data[0]); 105148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 105248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glActiveTexture(GL_TEXTURE6); 105348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBuffer(GL_TEXTURE_BUFFER, m_texture_buffer); 105448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBufferData(GL_TEXTURE_BUFFER, kBufferSize * sizeof(vec4), &texture_data[0], GL_DYNAMIC_DRAW); 105548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBuffer(GL_TEXTURE_BUFFER, 0); 105648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindTexture(GL_TEXTURE_BUFFER, m_texture[6]); 105748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA32F, m_texture_buffer); 105848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 105948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glActiveTexture(GL_TEXTURE7); 106048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, m_texture[7]); 106148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_RGBA32F, kWidth, kHeight, GL_FALSE); 106248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 106348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glActiveTexture(GL_TEXTURE8); 106448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, m_texture[8]); 106548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glTexImage3DMultisample(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, 4, GL_RGBA32F, kWidth, kHeight, kDepth, GL_FALSE); 106648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 106748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos // clear MS textures 106848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint fbo; 106948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGenFramebuffers(1, &fbo); 107048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindFramebuffer(GL_FRAMEBUFFER, fbo); 107148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_texture[7], 0); 107248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glClearBufferfv(GL_COLOR, 0, &vec4(123.0f)[0]); 107348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_texture[8], 0); 107448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glClearBufferfv(GL_COLOR, 0, &vec4(123.0f)[0]); 107548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteFramebuffers(1, &fbo); 107648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 107748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUseProgram(m_program); 107848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (dispatch_indirect) 107948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 108048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_dispatch_buffer == 0) 108148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGenBuffers(1, &m_dispatch_buffer); 108248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBuffer(GL_DISPATCH_INDIRECT_BUFFER, m_dispatch_buffer); 108348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBufferData(GL_DISPATCH_INDIRECT_BUFFER, sizeof(num_groups), &num_groups[0], GL_STATIC_DRAW); 108448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDispatchComputeIndirect(0); 108548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 108648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else 108748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 108848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDispatchCompute(num_groups.x(), num_groups.y(), num_groups.z()); 108948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 109048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 109148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer); 109248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT); 109348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, sizeof(vec4) * kBufferSize * 9, &buffer_data[0]); 109448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLuint index = 0; index < kBufferSize * 9; ++index) 109548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 109648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!IsEqual(buffer_data[index], vec4(123.0f))) 109748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1098910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() 1099910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << tcu::TestLog::Message << "Incorrect data at index " << index << "." << tcu::TestLog::EndMessage; 110048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return false; 110148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 110248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 110348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return true; 110448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 110548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 110648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Setup() 110748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 110848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_program = 0; 110948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_storage_buffer = 0; 111048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos memset(m_texture, 0, sizeof(m_texture)); 111148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_texture_buffer = 0; 111248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_dispatch_buffer = 0; 111348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 111448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 111548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 111648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Run() 111748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 111848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!RunIteration(uvec3(4, 4, 4), uvec3(8, 1, 1), false)) 111948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 112048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!RunIteration(uvec3(2, 4, 2), uvec3(2, 4, 1), true)) 112148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 112248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!RunIteration(uvec3(2, 2, 2), uvec3(2, 2, 2), false)) 112348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 112448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 112548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 112648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 112748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Cleanup() 112848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 112948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glActiveTexture(GL_TEXTURE0); 113048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUseProgram(0); 113148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteProgram(m_program); 113248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteBuffers(1, &m_storage_buffer); 113348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteTextures(9, m_texture); 113448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteBuffers(1, &m_texture_buffer); 113548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteBuffers(1, &m_dispatch_buffer); 113648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 113748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 113848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}; 113948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 114048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosclass BasicResourceImage : public ComputeShaderBase 114148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 114248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 114348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Title() 114448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 114548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "Compute Shader resources - Images"; 114648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 114748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 114848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Purpose() 114948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 115048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "Verify that reading/writing GPU memory via image variables work as expected."; 115148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 115248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 115348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Method() 115448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 115548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "1. Create CS which uses two image2D variables to read and write underlying GPU memory." NL 115648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "2. Dispatch CS with DispatchCompute and DispatchComputeIndirect commands." NL 115748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "3. Verify memory content." NL "4. Repeat for different texture and CS work sizes."; 115848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 115948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 116048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string PassCriteria() 116148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 116248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "Everything works as expected."; 116348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 116448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 116548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_program; 116648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_draw_program; 116748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_texture[2]; 116848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_dispatch_buffer; 116948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_vertex_array; 117048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 117148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::string GenSource(const uvec3& local_size, const uvec3& num_groups) 117248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 117348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const uvec3 global_size = local_size * num_groups; 117448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::stringstream ss; 117548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos ss << NL "layout(local_size_x = " << local_size.x() << ", local_size_y = " << local_size.y() 117648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << ", local_size_z = " << local_size.z() 117748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << ") in;" NL "layout(rgba32f) coherent uniform image2D g_image1;" NL 117848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "layout(rgba32f) uniform image2D g_image2;" NL "const uvec3 kGlobalSize = uvec3(" 117948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << global_size.x() << ", " << global_size.y() << ", " << global_size.z() 118048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << ");" NL "void main() {" NL 118148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " if (gl_GlobalInvocationID.x >= kGlobalSize.x || gl_GlobalInvocationID.y >= kGlobalSize.y) return;" NL 118248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " vec4 color = vec4(gl_GlobalInvocationID.x + gl_GlobalInvocationID.y) / 255.0;" NL 118348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " imageStore(g_image1, ivec2(gl_GlobalInvocationID), color);" NL 118448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " vec4 c = imageLoad(g_image1, ivec2(gl_GlobalInvocationID));" NL 118548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " imageStore(g_image2, ivec2(gl_GlobalInvocationID), c);" NL "}"; 118648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ss.str(); 118748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 118848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 118948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos bool RunIteration(const uvec3& local_size, const uvec3& num_groups, bool dispatch_indirect) 119048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 119148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_program != 0) 119248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteProgram(m_program); 119348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_program = CreateComputeProgram(GenSource(local_size, num_groups)); 119448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glLinkProgram(m_program); 119548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!CheckProgram(m_program)) 119648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return false; 119748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 119848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUseProgram(m_program); 119948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUniform1i(glGetUniformLocation(m_program, "g_image1"), 0); 120048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUniform1i(glGetUniformLocation(m_program, "g_image2"), 1); 120148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUseProgram(0); 120248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 120348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLint kWidth = static_cast<GLint>(local_size.x() * num_groups.x()); 120448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLint kHeight = static_cast<GLint>(local_size.y() * num_groups.y()); 120548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLint kDepth = static_cast<GLint>(local_size.z() * num_groups.z()); 120648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLuint kSize = kWidth * kHeight * kDepth; 120748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 120848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::vector<vec4> data(kSize); 120948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_texture[0] == 0) 121048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGenTextures(2, m_texture); 121148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 121248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (int i = 0; i < 2; ++i) 121348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 121448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindTexture(GL_TEXTURE_2D, m_texture[i]); 121548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 121648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, kWidth, kHeight, 0, GL_RGBA, GL_FLOAT, &data[0]); 121748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 121848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindTexture(GL_TEXTURE_2D, 0); 121948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 122048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindImageTexture(0, m_texture[0], 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32F); 122148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindImageTexture(1, m_texture[1], 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA32F); 122248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUseProgram(m_program); 122348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (dispatch_indirect) 122448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 122548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_dispatch_buffer == 0) 122648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGenBuffers(1, &m_dispatch_buffer); 122748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBuffer(GL_DISPATCH_INDIRECT_BUFFER, m_dispatch_buffer); 122848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBufferData(GL_DISPATCH_INDIRECT_BUFFER, sizeof(num_groups), &num_groups[0], GL_STATIC_DRAW); 122948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDispatchComputeIndirect(0); 123048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 123148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else 123248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 123348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDispatchCompute(num_groups.x(), num_groups.y(), num_groups.z()); 123448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 123548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT); 123648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 123748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glClear(GL_COLOR_BUFFER_BIT); 123848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glActiveTexture(GL_TEXTURE0); 123948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindTexture(GL_TEXTURE_2D, m_texture[0]); 124048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glActiveTexture(GL_TEXTURE1); 124148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindTexture(GL_TEXTURE_2D, m_texture[1]); 124248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUseProgram(m_draw_program); 124348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindVertexArray(m_vertex_array); 124448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glViewport(0, 0, kWidth, kHeight); 124548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, 1); 124648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 124748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::vector<vec4> display(kWidth * kHeight); 124848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glReadPixels(0, 0, kWidth, kHeight, GL_RGBA, GL_FLOAT, &display[0]); 124948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 125048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (int y = 0; y < kHeight; ++y) 125148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 125248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (int x = 0; x < kWidth; ++x) 125348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 125448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (y >= getWindowHeight() || x >= getWindowWidth()) 125548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 125648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos continue; 125748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 125848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const vec4 c = vec4(float(y + x) / 255.0f); 125948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!ColorEqual(display[y * kWidth + x], c, g_color_eps)) 126048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1261910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() 1262910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << tcu::TestLog::Message << "Got " << display[y * kWidth + x].x() << ", " 1263910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << display[y * kWidth + x].y() << ", " << display[y * kWidth + x].z() << ", " 1264910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << display[y * kWidth + x].w() << ", expected " << c.x() << ", " << c.y() << ", " << c.z() 1265910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << ", " << c.w() << " at " << x << ", " << y << tcu::TestLog::EndMessage; 126648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return false; 126748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 126848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 126948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 127048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 127148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return true; 127248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 127348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 127448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Setup() 127548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 127648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_program = 0; 127748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos memset(m_texture, 0, sizeof(m_texture)); 127848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_dispatch_buffer = 0; 127948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 128048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 128148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 128248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Run() 128348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 128448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 128548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* const glsl_vs = 128648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos NL "out StageData {" NL " vec2 texcoord;" NL "} vs_out;" NL 128748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "const vec2 g_quad[] = vec2[](vec2(-1, -1), vec2(1, -1), vec2(-1, 1), vec2(1, 1));" NL "void main() {" NL 128848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " gl_Position = vec4(g_quad[gl_VertexID], 0, 1);" NL 128948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " vs_out.texcoord = 0.5 + 0.5 * g_quad[gl_VertexID];" NL "}"; 129048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 129148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* glsl_fs = 129248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos NL "in StageData {" NL " vec2 texcoord;" NL "} fs_in;" NL "layout(location = 0) out vec4 o_color;" NL 129348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "uniform sampler2D g_image1;" NL "uniform sampler2D g_image2;" NL "void main() {" NL 129448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " vec4 c1 = texture(g_image1, fs_in.texcoord);" NL " vec4 c2 = texture(g_image2, fs_in.texcoord);" NL 129548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " if (c1 == c2) o_color = c1;" NL " else o_color = vec4(1, 0, 0, 1);" NL "}"; 129648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 129748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_draw_program = CreateProgram(glsl_vs, glsl_fs); 129848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glLinkProgram(m_draw_program); 129948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!CheckProgram(m_draw_program)) 130048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 130148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 130248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUseProgram(m_draw_program); 130348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUniform1i(glGetUniformLocation(m_draw_program, "g_image1"), 0); 130448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUniform1i(glGetUniformLocation(m_draw_program, "g_image2"), 1); 130548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUseProgram(0); 130648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 130748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGenVertexArrays(1, &m_vertex_array); 130848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 130948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!pixelFormat.alphaBits) 131048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1311910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() 1312910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << tcu::TestLog::Message << "Test requires default framebuffer alpha bits" << tcu::TestLog::EndMessage; 131348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 131448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 131548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 131648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!RunIteration(uvec3(8, 16, 1), uvec3(8, 4, 1), true)) 131748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 131848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!RunIteration(uvec3(4, 32, 1), uvec3(16, 2, 1), false)) 131948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 132048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!RunIteration(uvec3(16, 4, 1), uvec3(4, 16, 1), false)) 132148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 132248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!RunIteration(uvec3(8, 8, 1), uvec3(8, 8, 1), true)) 132348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 132448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 132548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 132648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 132748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 132848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Cleanup() 132948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 133048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUseProgram(0); 133148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteProgram(m_program); 133248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteProgram(m_draw_program); 133348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteVertexArrays(1, &m_vertex_array); 133448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteTextures(2, m_texture); 133548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteBuffers(1, &m_dispatch_buffer); 133648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glViewport(0, 0, getWindowWidth(), getWindowHeight()); 133748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 133848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 133948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}; 134048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 134148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosclass BasicResourceAtomicCounter : public ComputeShaderBase 134248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 134348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 134448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Title() 134548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 134648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return "Compute Shader resources - Atomic Counters"; 134748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 134848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 134948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Purpose() 135048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 135148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL 135248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "1. Verify that Atomic Counters work as expected in CS." NL 135348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "2. Verify that built-in functions: atomicCounterIncrement and atomicCounterDecrement work correctly." NL 135448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "3. Verify that GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_COMPUTE_SHADER is accepted by" NL 135548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " GetActiveAtomicCounterBufferiv command."; 135648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 135748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 135848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Method() 135948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 136048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL 136148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "1. Create CS which uses two atomic_uint variables." NL 136248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "2. In CS write values returned by atomicCounterIncrement and atomicCounterDecrement functions to SSBO." NL 136348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "3. Dispatch CS with DispatchCompute and DispatchComputeIndirect commands." NL "4. Verify SSBO content." NL 136448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "5. Repeat for different buffer and CS work sizes."; 136548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 136648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 136748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string PassCriteria() 136848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 136948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return "Everything works as expected."; 137048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 137148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 137248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_program; 137348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_storage_buffer; 137448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_counter_buffer[2]; 137548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_dispatch_buffer; 137648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 137748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::string GenSource(const uvec3& local_size, const uvec3& num_groups) 137848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 137948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const uvec3 global_size = local_size * num_groups; 138048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::stringstream ss; 138148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos ss << NL "layout(local_size_x = " << local_size.x() << ", local_size_y = " << local_size.y() 138248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << ", local_size_z = " << local_size.z() 138348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << ") in;" NL "layout(std430, binding = 0) buffer Output {" NL " uint inc_data[" 138448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << global_size.x() * global_size.y() * global_size.z() << "];" NL " uint dec_data[" 138548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << global_size.x() * global_size.y() * global_size.z() 138648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << "];" NL "};" NL "layout(binding = 0, offset = 0) uniform atomic_uint g_inc_counter;" NL 138748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "layout(binding = 1, offset = 0) uniform atomic_uint g_dec_counter;" NL "void main() {" NL 138848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " const uint index = atomicCounterIncrement(g_inc_counter);" NL " inc_data[index] = index;" NL 138948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " dec_data[index] = atomicCounterDecrement(g_dec_counter);" NL "}"; 139048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ss.str(); 139148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 139248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 139348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos bool RunIteration(const uvec3& local_size, const uvec3& num_groups, bool dispatch_indirect) 139448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 139548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_program != 0) 139648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteProgram(m_program); 139748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_program = CreateComputeProgram(GenSource(local_size, num_groups)); 139848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glLinkProgram(m_program); 139948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!CheckProgram(m_program)) 140048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return false; 140148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 140248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLint p[2] = { 0 }; 140348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetActiveAtomicCounterBufferiv(m_program, 0, GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_COMPUTE_SHADER, &p[0]); 140448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetActiveAtomicCounterBufferiv(m_program, 1, GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_COMPUTE_SHADER, &p[1]); 140548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 140648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (p[0] == GL_FALSE || p[1] == GL_FALSE) 140748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1408910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() 1409910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << tcu::TestLog::Message << "ATOMIC_COUNTER_BUFFER_REFERENCED_BY_COMPUTE_SHADER should be TRUE." 1410910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << tcu::TestLog::EndMessage; 141148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return false; 141248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 141348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 141448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLint kWidth = static_cast<GLint>(local_size.x() * num_groups.x()); 141548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLint kHeight = static_cast<GLint>(local_size.y() * num_groups.y()); 141648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLint kDepth = static_cast<GLint>(local_size.z() * num_groups.z()); 141748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLuint kSize = kWidth * kHeight * kDepth; 141848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 141948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_storage_buffer == 0) 142048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGenBuffers(1, &m_storage_buffer); 142148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_storage_buffer); 142248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(GLuint) * kSize * 2, NULL, GL_DYNAMIC_DRAW); 142348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0); 142448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 142548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_counter_buffer[0] == 0) 142648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGenBuffers(2, m_counter_buffer); 142748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 142848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0, m_counter_buffer[0]); 142948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBufferData(GL_ATOMIC_COUNTER_BUFFER, sizeof(GLuint), NULL, GL_STREAM_DRAW); 143048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *static_cast<GLuint*>(glMapBuffer(GL_ATOMIC_COUNTER_BUFFER, GL_WRITE_ONLY)) = 0; 143148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUnmapBuffer(GL_ATOMIC_COUNTER_BUFFER); 143248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 143348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 1, m_counter_buffer[1]); 143448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBufferData(GL_ATOMIC_COUNTER_BUFFER, sizeof(GLuint), NULL, GL_STREAM_DRAW); 143548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *static_cast<GLuint*>(glMapBuffer(GL_ATOMIC_COUNTER_BUFFER, GL_WRITE_ONLY)) = kSize; 143648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUnmapBuffer(GL_ATOMIC_COUNTER_BUFFER); 143748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 143848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, 0); 143948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 144048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUseProgram(m_program); 144148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (dispatch_indirect) 144248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 144348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_dispatch_buffer == 0) 144448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGenBuffers(1, &m_dispatch_buffer); 144548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBuffer(GL_DISPATCH_INDIRECT_BUFFER, m_dispatch_buffer); 144648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBufferData(GL_DISPATCH_INDIRECT_BUFFER, sizeof(num_groups), &num_groups[0], GL_STATIC_DRAW); 144748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDispatchComputeIndirect(0); 144848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 144948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else 145048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 145148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDispatchCompute(num_groups.x(), num_groups.y(), num_groups.z()); 145248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 145348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 145448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::vector<GLuint> data(kSize); 145548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer); 145648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT); 145748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, sizeof(GLuint) * kSize, &data[0]); 145848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 145948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLuint i = 0; i < kSize; ++i) 146048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 146148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (data[i] != i) 146248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1463910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() << tcu::TestLog::Message << "Value at index " << i << " is " 1464910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << data[i] << " should be " << i << "." << tcu::TestLog::EndMessage; 146548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return false; 146648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 146748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 146848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 146948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint value; 147048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, m_counter_buffer[0]); 147148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetBufferSubData(GL_ATOMIC_COUNTER_BUFFER, 0, sizeof(GLuint), &value); 147248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (value != kSize) 147348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1474910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() << tcu::TestLog::Message << "Final atomic counter value (buffer 0) is " 1475910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << value << " should be " << kSize << "." << tcu::TestLog::EndMessage; 147648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return false; 147748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 147848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 147948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, m_counter_buffer[1]); 148048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetBufferSubData(GL_ATOMIC_COUNTER_BUFFER, 0, sizeof(GLuint), &value); 148148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (value != 0) 148248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1483910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() << tcu::TestLog::Message << "Final atomic counter value (buffer 1) is " 1484910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << value << " should be 0." << tcu::TestLog::EndMessage; 148548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return false; 148648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 148748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 148848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return true; 148948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 149048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 149148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Setup() 149248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 149348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_program = 0; 149448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_storage_buffer = 0; 149548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos memset(m_counter_buffer, 0, sizeof(m_counter_buffer)); 149648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_dispatch_buffer = 0; 149748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 149848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 149948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 150048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Run() 150148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 150248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!RunIteration(uvec3(4, 3, 2), uvec3(2, 3, 4), false)) 150348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 150448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!RunIteration(uvec3(1, 1, 1), uvec3(1, 1, 1), true)) 150548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 150648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!RunIteration(uvec3(1, 6, 1), uvec3(1, 1, 8), false)) 150748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 150848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!RunIteration(uvec3(4, 1, 2), uvec3(10, 3, 4), true)) 150948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 151048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 151148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 151248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 151348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Cleanup() 151448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 151548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUseProgram(0); 151648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteProgram(m_program); 151748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteBuffers(2, m_counter_buffer); 151848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteBuffers(1, &m_dispatch_buffer); 151948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteBuffers(1, &m_storage_buffer); 152048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 152148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 152248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}; 152348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 152448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosclass BasicResourceSubroutine : public ComputeShaderBase 152548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 152648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 152748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Title() 152848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 152948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return "Compute Shader resources - Subroutines"; 153048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 153148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 153248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Purpose() 153348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 153448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "1. Verify that subroutines work as expected in CS." NL 153548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "2. Verify that subroutines array can be indexed with gl_WorkGroupID built-in variable." NL 153648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "3. Verify that atomicCounterIncrement, imageLoad and texelFetch functions" NL 153748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " work as expected when called in CS from subroutine."; 153848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 153948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 154048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Method() 154148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 154248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "1. Create CS which uses array of subroutines." NL 154348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "2. In CS index subroutine array with gl_WorkGroupID built-in variable." NL 154448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "3. In each subroutine load data from SSBO0 and write it to SSBO1." NL 154548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "3. Dispatch CS with DispatchCompute and DispatchComputeIndirect commands." NL 154648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "4. Verify SSBO1 content." NL "5. Repeat for different buffer and CS work sizes."; 154748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 154848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 154948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string PassCriteria() 155048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 155148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return "Everything works as expected."; 155248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 155348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 155448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_program; 155548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_atomic_counter_buffer; 155648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_storage_buffer[2]; 155748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_buffer[2]; 155848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_texture_buffer[2]; 155948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 156048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Setup() 156148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 156248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_program = 0; 156348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_atomic_counter_buffer = 0; 156448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos memset(m_storage_buffer, 0, sizeof(m_storage_buffer)); 156548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos memset(m_buffer, 0, sizeof(m_buffer)); 156648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos memset(m_texture_buffer, 0, sizeof(m_texture_buffer)); 156748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 156848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 156948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 157048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Run() 157148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 157248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* const glsl_cs = 157348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos NL "layout(local_size_x = 16) in;" NL "layout(binding = 1, std430) buffer Input {" NL " uvec4 data[16];" NL 157448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "} g_input;" NL "layout(std430, binding = 0) buffer Output {" NL " uvec4 g_output[64];" NL "};" NL 157548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine void ComputeType();" NL "subroutine uniform ComputeType Compute[4];" NL 157648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "layout(binding = 0, offset = 0) uniform atomic_uint g_atomic_counter;" NL 157748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "layout(rgba32ui) readonly uniform uimageBuffer g_image_buffer;" NL 157848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "uniform usamplerBuffer g_sampler_buffer;" NL "subroutine(ComputeType)" NL "void Compute0() {" NL 157948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " const uint index = atomicCounterIncrement(g_atomic_counter);" NL 158048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " g_output[index] = uvec4(index);" NL "}" NL "subroutine(ComputeType)" NL "void Compute1() {" NL 158148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " g_output[gl_GlobalInvocationID.x] = g_input.data[gl_LocalInvocationIndex];" NL "}" NL 158248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine(ComputeType)" NL "void Compute2() {" NL 158348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " g_output[gl_GlobalInvocationID.x] = imageLoad(g_image_buffer, int(gl_LocalInvocationIndex));" NL 158448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}" NL "subroutine(ComputeType)" NL "void Compute3() {" NL 158548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " g_output[gl_GlobalInvocationID.x] = texelFetch(g_sampler_buffer, int(gl_LocalInvocationIndex));" NL 158648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}" NL "void main() {" NL " Compute[gl_WorkGroupID.x]();" NL "}"; 158748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_program = CreateComputeProgram(glsl_cs); 158848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glLinkProgram(m_program); 158948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!CheckProgram(m_program)) 159048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 159148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 159248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGenBuffers(2, m_storage_buffer); 159348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* output buffer */ 159448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 159548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::vector<uvec4> data(64, uvec4(0xffff)); 159648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer[0]); 159748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(uvec4) * 64, &data[0], GL_DYNAMIC_DRAW); 159848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 159948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* input buffer */ 160048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 160148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::vector<uvec4> data(16); 160248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLuint i = 0; i < 16; ++i) 160348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos data[i] = uvec4(i + 16); 160448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer[1]); 160548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(uvec4) * 16, &data[0], GL_DYNAMIC_DRAW); 160648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 160748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0); 160848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 160948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGenBuffers(1, &m_atomic_counter_buffer); 161048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0, m_atomic_counter_buffer); 161148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBufferData(GL_ATOMIC_COUNTER_BUFFER, sizeof(GLuint), NULL, GL_STREAM_DRAW); 161248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *static_cast<GLuint*>(glMapBuffer(GL_ATOMIC_COUNTER_BUFFER, GL_WRITE_ONLY)) = 0; 161348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUnmapBuffer(GL_ATOMIC_COUNTER_BUFFER); 161448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 161548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGenBuffers(2, m_buffer); 161648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* image buffer */ 161748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 161848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::vector<uvec4> data(16); 161948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLuint i = 0; i < 16; ++i) 162048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos data[i] = uvec4(i + 32); 162148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBuffer(GL_TEXTURE_BUFFER, m_buffer[0]); 162248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBufferData(GL_TEXTURE_BUFFER, sizeof(uvec4) * 16, &data[0], GL_STATIC_DRAW); 162348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 162448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* texture buffer */ 162548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 162648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::vector<uvec4> data(16); 162748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLuint i = 0; i < 16; ++i) 162848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos data[i] = uvec4(i + 48); 162948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBuffer(GL_TEXTURE_BUFFER, m_buffer[1]); 163048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBufferData(GL_TEXTURE_BUFFER, sizeof(uvec4) * 16, &data[0], GL_STATIC_DRAW); 163148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 163248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBuffer(GL_TEXTURE_BUFFER, 0); 163348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 163448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGenTextures(2, m_texture_buffer); 163548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindTexture(GL_TEXTURE_BUFFER, m_texture_buffer[0]); 163648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA32UI, m_buffer[0]); 163748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindTexture(GL_TEXTURE_BUFFER, m_texture_buffer[1]); 163848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA32UI, m_buffer[1]); 163948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindTexture(GL_TEXTURE_BUFFER, 0); 164048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 164148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLuint index_compute0 = glGetSubroutineIndex(m_program, GL_COMPUTE_SHADER, "Compute0"); 164248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLuint index_compute1 = glGetSubroutineIndex(m_program, GL_COMPUTE_SHADER, "Compute1"); 164348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLuint index_compute2 = glGetSubroutineIndex(m_program, GL_COMPUTE_SHADER, "Compute2"); 164448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLuint index_compute3 = glGetSubroutineIndex(m_program, GL_COMPUTE_SHADER, "Compute3"); 164548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLint loc_compute0 = glGetSubroutineUniformLocation(m_program, GL_COMPUTE_SHADER, "Compute[0]"); 164648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLint loc_compute1 = glGetSubroutineUniformLocation(m_program, GL_COMPUTE_SHADER, "Compute[1]"); 164748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLint loc_compute2 = glGetSubroutineUniformLocation(m_program, GL_COMPUTE_SHADER, "Compute[2]"); 164848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLint loc_compute3 = glGetSubroutineUniformLocation(m_program, GL_COMPUTE_SHADER, "Compute[3]"); 164948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 165048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos // bind resources 165148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_storage_buffer[0]); 165248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_storage_buffer[1]); 165348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0, m_atomic_counter_buffer); 165448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindImageTexture(0, m_texture_buffer[0], 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA32UI); 165548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glActiveTexture(GL_TEXTURE0); 165648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindTexture(GL_TEXTURE_BUFFER, m_texture_buffer[1]); 165748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 165848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUseProgram(m_program); 165948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 166048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos // setup subroutines 166148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint indices[4]; 166248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos indices[loc_compute0] = index_compute0; 166348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos indices[loc_compute1] = index_compute1; 166448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos indices[loc_compute2] = index_compute2; 166548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos indices[loc_compute3] = index_compute3; 166648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUniformSubroutinesuiv(GL_COMPUTE_SHADER, 4, indices); 166748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 166848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDispatchCompute(4, 1, 1); 166948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 167048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::vector<uvec4> data(64); 167148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer[0]); 167248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT); 167348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, sizeof(uvec4) * 64, &data[0]); 167448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 167548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLuint i = 0; i < 64; ++i) 167648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 167748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!IsEqual(data[i], uvec4(i))) 167848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1679910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() 1680910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << tcu::TestLog::Message << "Invalid value at index " << i << "." << tcu::TestLog::EndMessage; 168148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 168248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 168348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 168448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 168548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint value; 168648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, m_atomic_counter_buffer); 168748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetBufferSubData(GL_ATOMIC_COUNTER_BUFFER, 0, sizeof(GLuint), &value); 168848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (value != 16) 168948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1690910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() << tcu::TestLog::Message << "Final atomic counter value is " << value 1691910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << " should be 16." << tcu::TestLog::EndMessage; 169248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 169348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 169448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 169548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 169648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 169748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 169848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Cleanup() 169948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 170048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUseProgram(0); 170148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteProgram(m_program); 170248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteBuffers(1, &m_atomic_counter_buffer); 170348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteBuffers(2, m_storage_buffer); 170448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteBuffers(2, m_buffer); 170548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteTextures(2, m_texture_buffer); 170648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 170748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 170848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}; 170948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 171048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosclass BasicResourceUniform : public ComputeShaderBase 171148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 171248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 171348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Title() 171448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 171548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return "Compute Shader resources - Uniforms"; 171648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 171748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 171848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Purpose() 171948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 172048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "1. Verify that all types of uniform variables work as expected in CS." NL 172148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "2. Verify that uniform variables can be updated with Uniform* and ProgramUniform* commands." NL 172248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "3. Verify that re-linking CS program works as expected."; 172348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 172448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 172548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Method() 172648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 172748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "1. Create CS which uses all (single precision and integer) types of uniform variables." NL 172848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "2. Update uniform variables with ProgramUniform* commands." NL 172948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "3. Verify that uniform variables were updated correctly." NL "4. Re-link CS program." NL 173048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "5. Update uniform variables with Uniform* commands." NL 173148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "6. Verify that uniform variables were updated correctly."; 173248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 173348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 173448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string PassCriteria() 173548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 173648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return "Everything works as expected."; 173748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 173848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 173948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_program; 174048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_storage_buffer; 174148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 174248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Setup() 174348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 174448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_program = 0; 174548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_storage_buffer = 0; 174648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 174748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 174848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 174948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Run() 175048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 175148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* const glsl_cs = NL 175248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "layout(local_size_x = 1) in;" NL "buffer Result {" NL " int g_result;" NL "};" NL "uniform float g_0;" NL 175348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "uniform vec2 g_1;" NL "uniform vec3 g_2;" NL "uniform vec4 g_3;" NL "uniform mat2 g_4;" NL 175448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "uniform mat2x3 g_5;" NL "uniform mat2x4 g_6;" NL "uniform mat3x2 g_7;" NL "uniform mat3 g_8;" NL 175548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "uniform mat3x4 g_9;" NL "uniform mat4x2 g_10;" NL "uniform mat4x3 g_11;" NL "uniform mat4 g_12;" NL 175648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "uniform int g_13;" NL "uniform ivec2 g_14;" NL "uniform ivec3 g_15;" NL "uniform ivec4 g_16;" NL 175748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "uniform uint g_17;" NL "uniform uvec2 g_18;" NL "uniform uvec3 g_19;" NL "uniform uvec4 g_20;" NL NL 175848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void main() {" NL " g_result = 1;" NL NL " if (g_0 != 1.0) g_result = 0;" NL 175948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " if (g_1 != vec2(2.0, 3.0)) g_result = 0;" NL " if (g_2 != vec3(4.0, 5.0, 6.0)) g_result = 0;" NL 176048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " if (g_3 != vec4(7.0, 8.0, 9.0, 10.0)) g_result = 0;" NL NL 176148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " if (g_4 != mat2(11.0, 12.0, 13.0, 14.0)) g_result = 0;" NL 176248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " if (g_5 != mat2x3(15.0, 16.0, 17.0, 18.0, 19.0, 20.0)) g_result = 0;" NL 176348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " if (g_6 != mat2x4(21.0, 22.0, 23.0, 24.0, 25.0, 26.0, 27.0, 28.0)) g_result = 0;" NL NL 176448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " if (g_7 != mat3x2(29.0, 30.0, 31.0, 32.0, 33.0, 34.0)) g_result = 0;" NL 176548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " if (g_8 != mat3(35.0, 36.0, 37.0, 38.0, 39.0, 40.0, 41.0, 42.0, 43.0)) g_result = 0;" NL 176648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " if (g_9 != mat3x4(44.0, 45.0, 46.0, 47.0, 48.0, 49.0, 50.0, 51.0, 52.0, 53.0, 54.0, 55.0)) g_result = " 176748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "0;" NL NL " if (g_10 != mat4x2(56.0, 57.0, 58.0, 59.0, 60.0, 61.0, 62.0, 63.0)) g_result = 0;" NL 176848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " if (g_11 != mat4x3(63.0, 64.0, 65.0, 66.0, 67.0, 68.0, 69.0, 70.0, 71.0, 27.0, 73, 74.0)) g_result = " 176948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "0;" NL " if (g_12 != mat4(75.0, 76.0, 77.0, 78.0, 79.0, 80.0, 81.0, 82.0, 83.0, 84.0, 85.0, 86.0, 87.0, " 177048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "88.0, 89.0, 90.0)) g_result = 0;" NL NL " if (g_13 != 91) g_result = 0;" NL 177148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " if (g_14 != ivec2(92, 93)) g_result = 0;" NL " if (g_15 != ivec3(94, 95, 96)) g_result = 0;" NL 177248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " if (g_16 != ivec4(97, 98, 99, 100)) g_result = 0;" NL NL " if (g_17 != 101u) g_result = 0;" NL 177348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " if (g_18 != uvec2(102u, 103u)) g_result = 0;" NL 177448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " if (g_19 != uvec3(104u, 105u, 106u)) g_result = 0;" NL 177548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " if (g_20 != uvec4(107u, 108u, 109u, 110u)) g_result = 0;" NL "}"; 177648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_program = CreateComputeProgram(glsl_cs); 177748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glLinkProgram(m_program); 177848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!CheckProgram(m_program)) 177948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 178048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 178148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGenBuffers(1, &m_storage_buffer); 178248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* create buffer */ 178348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 178448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const int data = 123; 178548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_storage_buffer); 178648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), &data, GL_STATIC_DRAW); 178748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 178848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 178948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glProgramUniform1f(m_program, glGetUniformLocation(m_program, "g_0"), 1.0f); 179048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glProgramUniform2f(m_program, glGetUniformLocation(m_program, "g_1"), 2.0f, 3.0f); 179148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glProgramUniform3f(m_program, glGetUniformLocation(m_program, "g_2"), 4.0f, 5.0f, 6.0f); 179248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glProgramUniform4f(m_program, glGetUniformLocation(m_program, "g_3"), 7.0f, 8.0f, 9.0f, 10.0f); 179348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 179448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* mat2 */ 179548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 179648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLfloat value[4] = { 11.0f, 12.0f, 13.0f, 14.0f }; 179748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glProgramUniformMatrix2fv(m_program, glGetUniformLocation(m_program, "g_4"), 1, GL_FALSE, value); 179848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 179948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* mat2x3 */ 180048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 180148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLfloat value[6] = { 15.0f, 16.0f, 17.0f, 18.0f, 19.0f, 20.0f }; 180248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glProgramUniformMatrix2x3fv(m_program, glGetUniformLocation(m_program, "g_5"), 1, GL_FALSE, value); 180348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 180448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* mat2x4 */ 180548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 180648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLfloat value[8] = { 21.0f, 22.0f, 23.0f, 24.0f, 25.0f, 26.0f, 27.0f, 28.0f }; 180748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glProgramUniformMatrix2x4fv(m_program, glGetUniformLocation(m_program, "g_6"), 1, GL_FALSE, value); 180848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 180948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 181048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* mat3x2 */ 181148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 181248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLfloat value[6] = { 29.0f, 30.0f, 31.0f, 32.0f, 33.0f, 34.0f }; 181348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glProgramUniformMatrix3x2fv(m_program, glGetUniformLocation(m_program, "g_7"), 1, GL_FALSE, value); 181448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 181548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* mat3 */ 181648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 181748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLfloat value[9] = { 35.0f, 36.0f, 37.0f, 38.0f, 39.0f, 40.0f, 41.0f, 42.0f, 43.0f }; 181848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glProgramUniformMatrix3fv(m_program, glGetUniformLocation(m_program, "g_8"), 1, GL_FALSE, value); 181948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 182048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* mat3x4 */ 182148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 182248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLfloat value[12] = { 44.0f, 45.0f, 46.0f, 47.0f, 48.0f, 49.0f, 182348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 50.0f, 51.0f, 52.0f, 53.0f, 54.0f, 55.0f }; 182448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glProgramUniformMatrix3x4fv(m_program, glGetUniformLocation(m_program, "g_9"), 1, GL_FALSE, value); 182548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 182648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 182748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* mat4x2 */ 182848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 182948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLfloat value[8] = { 56.0f, 57.0f, 58.0f, 59.0f, 60.0f, 61.0f, 62.0f, 63.0f }; 183048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glProgramUniformMatrix4x2fv(m_program, glGetUniformLocation(m_program, "g_10"), 1, GL_FALSE, value); 183148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 183248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* mat4x3 */ 183348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 183448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLfloat value[12] = { 183548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 63.0f, 64.0f, 65.0f, 66.0f, 67.0f, 68.0f, 69.0f, 70.0f, 71.0f, 27.0f, 73, 74.0f 183648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos }; 183748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glProgramUniformMatrix4x3fv(m_program, glGetUniformLocation(m_program, "g_11"), 1, GL_FALSE, value); 183848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 183948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* mat4 */ 184048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 184148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLfloat value[16] = { 75.0f, 76.0f, 77.0f, 78.0f, 79.0f, 80.0f, 81.0f, 82.0f, 184248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 83.0f, 84.0f, 85.0f, 86.0f, 87.0f, 88.0f, 89.0f, 90.0f }; 184348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glProgramUniformMatrix4fv(m_program, glGetUniformLocation(m_program, "g_12"), 1, GL_FALSE, value); 184448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 184548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 184648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glProgramUniform1i(m_program, glGetUniformLocation(m_program, "g_13"), 91); 184748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glProgramUniform2i(m_program, glGetUniformLocation(m_program, "g_14"), 92, 93); 184848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glProgramUniform3i(m_program, glGetUniformLocation(m_program, "g_15"), 94, 95, 96); 184948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glProgramUniform4i(m_program, glGetUniformLocation(m_program, "g_16"), 97, 98, 99, 100); 185048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 185148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glProgramUniform1ui(m_program, glGetUniformLocation(m_program, "g_17"), 101); 185248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glProgramUniform2ui(m_program, glGetUniformLocation(m_program, "g_18"), 102, 103); 185348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glProgramUniform3ui(m_program, glGetUniformLocation(m_program, "g_19"), 104, 105, 106); 185448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glProgramUniform4ui(m_program, glGetUniformLocation(m_program, "g_20"), 107, 108, 109, 110); 185548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 185648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUseProgram(m_program); 185748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDispatchCompute(1, 1, 1); 185848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT); 185948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 186048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 186148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos int data; 186248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, sizeof(data), &data); 186348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (data != 1) 186448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1865910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() 1866910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << tcu::TestLog::Message << "Data is " << data << " should be 1." << tcu::TestLog::EndMessage; 186748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 186848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 186948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 187048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 187148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos // re-link program (all uniforms will be set to zero) 187248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glLinkProgram(m_program); 187348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 187448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 187548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const int data = 123; 187648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, sizeof(data), &data); 187748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 187848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 187948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUniform1f(glGetUniformLocation(m_program, "g_0"), 1.0f); 188048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUniform2f(glGetUniformLocation(m_program, "g_1"), 2.0f, 3.0f); 188148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUniform3f(glGetUniformLocation(m_program, "g_2"), 4.0f, 5.0f, 6.0f); 188248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUniform4f(glGetUniformLocation(m_program, "g_3"), 7.0f, 8.0f, 9.0f, 10.0f); 188348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 188448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* mat2 */ 188548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 188648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLfloat value[4] = { 11.0f, 12.0f, 13.0f, 14.0f }; 188748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUniformMatrix2fv(glGetUniformLocation(m_program, "g_4"), 1, GL_FALSE, value); 188848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 188948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* mat2x3 */ 189048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 189148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLfloat value[6] = { 15.0f, 16.0f, 17.0f, 18.0f, 19.0f, 20.0f }; 189248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUniformMatrix2x3fv(glGetUniformLocation(m_program, "g_5"), 1, GL_FALSE, value); 189348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 189448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* mat2x4 */ 189548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 189648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLfloat value[8] = { 21.0f, 22.0f, 23.0f, 24.0f, 25.0f, 26.0f, 27.0f, 28.0f }; 189748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUniformMatrix2x4fv(glGetUniformLocation(m_program, "g_6"), 1, GL_FALSE, value); 189848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 189948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 190048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* mat3x2 */ 190148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 190248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLfloat value[6] = { 29.0f, 30.0f, 31.0f, 32.0f, 33.0f, 34.0f }; 190348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUniformMatrix3x2fv(glGetUniformLocation(m_program, "g_7"), 1, GL_FALSE, value); 190448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 190548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* mat3 */ 190648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 190748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLfloat value[9] = { 35.0f, 36.0f, 37.0f, 38.0f, 39.0f, 40.0f, 41.0f, 42.0f, 43.0f }; 190848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUniformMatrix3fv(glGetUniformLocation(m_program, "g_8"), 1, GL_FALSE, value); 190948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 191048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* mat3x4 */ 191148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 191248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLfloat value[12] = { 44.0f, 45.0f, 46.0f, 47.0f, 48.0f, 49.0f, 191348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 50.0f, 51.0f, 52.0f, 53.0f, 54.0f, 55.0f }; 191448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUniformMatrix3x4fv(glGetUniformLocation(m_program, "g_9"), 1, GL_FALSE, value); 191548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 191648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 191748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* mat4x2 */ 191848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 191948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLfloat value[8] = { 56.0f, 57.0f, 58.0f, 59.0f, 60.0f, 61.0f, 62.0f, 63.0f }; 192048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUniformMatrix4x2fv(glGetUniformLocation(m_program, "g_10"), 1, GL_FALSE, value); 192148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 192248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* mat4x3 */ 192348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 192448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLfloat value[12] = { 192548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 63.0f, 64.0f, 65.0f, 66.0f, 67.0f, 68.0f, 69.0f, 70.0f, 71.0f, 27.0f, 73, 74.0f 192648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos }; 192748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUniformMatrix4x3fv(glGetUniformLocation(m_program, "g_11"), 1, GL_FALSE, value); 192848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 192948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* mat4 */ 193048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 193148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLfloat value[16] = { 75.0f, 76.0f, 77.0f, 78.0f, 79.0f, 80.0f, 81.0f, 82.0f, 193248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 83.0f, 84.0f, 85.0f, 86.0f, 87.0f, 88.0f, 89.0f, 90.0f }; 193348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUniformMatrix4fv(glGetUniformLocation(m_program, "g_12"), 1, GL_FALSE, value); 193448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 193548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 193648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUniform1i(glGetUniformLocation(m_program, "g_13"), 91); 193748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUniform2i(glGetUniformLocation(m_program, "g_14"), 92, 93); 193848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUniform3i(glGetUniformLocation(m_program, "g_15"), 94, 95, 96); 193948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUniform4i(glGetUniformLocation(m_program, "g_16"), 97, 98, 99, 100); 194048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 194148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUniform1ui(glGetUniformLocation(m_program, "g_17"), 101); 194248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUniform2ui(glGetUniformLocation(m_program, "g_18"), 102, 103); 194348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUniform3ui(glGetUniformLocation(m_program, "g_19"), 104, 105, 106); 194448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUniform4ui(glGetUniformLocation(m_program, "g_20"), 107, 108, 109, 110); 194548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 194648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDispatchCompute(1, 1, 1); 194748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT); 194848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 194948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* validate */ 195048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 195148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos int data; 195248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, sizeof(data), &data); 195348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (data != 1) 195448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1955910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() 1956910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << tcu::TestLog::Message << "Data is " << data << " should be 1." << tcu::TestLog::EndMessage; 195748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 195848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 195948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 196048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 196148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 196248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 196348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 196448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Cleanup() 196548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 196648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUseProgram(0); 196748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteProgram(m_program); 196848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteBuffers(1, &m_storage_buffer); 196948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 197048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 197148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}; 197248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 197348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosclass BasicBuiltinVariables : public ComputeShaderBase 197448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 197548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 197648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Title() 197748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 197848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return "CS built-in variables"; 197948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 198048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 198148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Purpose() 198248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 198348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "Verify that all (gl_WorkGroupSize, gl_WorkGroupID, gl_LocalInvocationID," NL 198448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "gl_GlobalInvocationID, gl_NumWorkGroups, gl_WorkGroupSize)" NL 198548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "CS built-in variables has correct values."; 198648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 198748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 198848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Method() 198948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 199048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "1. Create CS which writes all built-in variables to SSBO." NL 199148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "2. Dispatch CS with DispatchCompute and DispatchComputeIndirect commands." NL 199248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "3. Verify SSBO content." NL "4. Repeat for several different local and global work sizes."; 199348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 199448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 199548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string PassCriteria() 199648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 199748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return "Everything works as expected."; 199848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 199948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 200048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_program; 200148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_storage_buffer; 200248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_dispatch_buffer; 200348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 200448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::string GenSource(const uvec3& local_size, const uvec3& num_groups) 200548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 200648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const uvec3 global_size = local_size * num_groups; 200748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::stringstream ss; 200848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos ss << NL "layout(local_size_x = " << local_size.x() << ", local_size_y = " << local_size.y() 200948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << ", local_size_z = " << local_size.z() << ") in;" NL "const uvec3 kGlobalSize = uvec3(" << global_size.x() 201048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << ", " << global_size.y() << ", " << global_size.z() 201148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << ");" NL "layout(std430) buffer OutputBuffer {" NL " uvec4 num_work_groups[" 201248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << global_size.x() * global_size.y() * global_size.z() << "];" NL " uvec4 work_group_size[" 201348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << global_size.x() * global_size.y() * global_size.z() << "];" NL " uvec4 work_group_id[" 201448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << global_size.x() * global_size.y() * global_size.z() << "];" NL " uvec4 local_invocation_id[" 201548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << global_size.x() * global_size.y() * global_size.z() << "];" NL " uvec4 global_invocation_id[" 201648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << global_size.x() * global_size.y() * global_size.z() << "];" NL " uvec4 local_invocation_index[" 201748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << global_size.x() * global_size.y() * global_size.z() 201848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << "];" NL "} g_out_buffer;" NL "void main() {" NL 201948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " if ((gl_WorkGroupSize * gl_WorkGroupID + gl_LocalInvocationID) != gl_GlobalInvocationID) return;" NL 202048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " const uint global_index = gl_GlobalInvocationID.x +" NL 202148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " gl_GlobalInvocationID.y * kGlobalSize.x +" NL 202248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " gl_GlobalInvocationID.z * kGlobalSize.x * kGlobalSize.y;" NL 202348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " g_out_buffer.num_work_groups[global_index] = uvec4(gl_NumWorkGroups, 0);" NL 202448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " g_out_buffer.work_group_size[global_index] = uvec4(gl_WorkGroupSize, 0);" NL 202548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " g_out_buffer.work_group_id[global_index] = uvec4(gl_WorkGroupID, 0);" NL 202648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " g_out_buffer.local_invocation_id[global_index] = uvec4(gl_LocalInvocationID, 0);" NL 202748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " g_out_buffer.global_invocation_id[global_index] = uvec4(gl_GlobalInvocationID, 0);" NL 202848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " g_out_buffer.local_invocation_index[global_index] = uvec4(gl_LocalInvocationIndex);" NL "}"; 202948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ss.str(); 203048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 203148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 203248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos bool RunIteration(const uvec3& local_size, const uvec3& num_groups, bool dispatch_indirect) 203348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 203448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_program != 0) 203548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteProgram(m_program); 203648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_program = CreateComputeProgram(GenSource(local_size, num_groups)); 203748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glLinkProgram(m_program); 203848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!CheckProgram(m_program)) 203948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return false; 204048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 204148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLuint kBufferSize = 204248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos local_size.x() * num_groups.x() * local_size.y() * num_groups.y() * local_size.z() * num_groups.z(); 204348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 204448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::vector<uvec4> data(kBufferSize * 6); 204548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_storage_buffer == 0) 204648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGenBuffers(1, &m_storage_buffer); 204748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_storage_buffer); 204848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(uvec4) * kBufferSize * 6, &data[0], GL_DYNAMIC_DRAW); 204948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0); 205048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 205148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUseProgram(m_program); 205248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (dispatch_indirect) 205348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 205448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_dispatch_buffer == 0) 205548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGenBuffers(1, &m_dispatch_buffer); 205648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBuffer(GL_DISPATCH_INDIRECT_BUFFER, m_dispatch_buffer); 205748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBufferData(GL_DISPATCH_INDIRECT_BUFFER, sizeof(num_groups), &num_groups[0], GL_STATIC_DRAW); 205848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDispatchComputeIndirect(0); 205948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 206048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else 206148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 206248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDispatchCompute(num_groups.x(), num_groups.y(), num_groups.z()); 206348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 206448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 206548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer); 206648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT); 206748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, sizeof(uvec4) * kBufferSize * 6, &data[0]); 206848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 206948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos // gl_NumWorkGroups 207048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLuint index = 0; index < kBufferSize; ++index) 207148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 207248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!IsEqual(data[index], uvec4(num_groups.x(), num_groups.y(), num_groups.z(), 0))) 207348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 2074910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() 2075910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << tcu::TestLog::Message << "gl_NumWorkGroups: Invalid data at index " << index << "." 2076910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << tcu::TestLog::EndMessage; 207748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return false; 207848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 207948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 208048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos // gl_WorkGroupSize 208148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLuint index = kBufferSize; index < 2 * kBufferSize; ++index) 208248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 208348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!IsEqual(data[index], uvec4(local_size.x(), local_size.y(), local_size.z(), 0))) 208448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 2085910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() 2086910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << tcu::TestLog::Message << "gl_WorkGroupSize: Invalid data at index " << index << "." 2087910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << tcu::TestLog::EndMessage; 208848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return false; 208948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 209048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 209148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos // gl_WorkGroupID 209248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLuint index = 2 * kBufferSize; index < 3 * kBufferSize; ++index) 209348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 209448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos uvec3 expected = IndexTo3DCoord(index - 2 * kBufferSize, local_size.x() * num_groups.x(), 209548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos local_size.y() * num_groups.y()); 209648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos expected.x() /= local_size.x(); 209748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos expected.y() /= local_size.y(); 209848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos expected.z() /= local_size.z(); 209948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!IsEqual(data[index], uvec4(expected.x(), expected.y(), expected.z(), 0))) 210048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 2101910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() << tcu::TestLog::Message << "gl_WorkGroupID: Invalid data at index " 2102910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << index << "." << tcu::TestLog::EndMessage; 210348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return false; 210448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 210548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 210648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos // gl_LocalInvocationID 210748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLuint index = 3 * kBufferSize; index < 4 * kBufferSize; ++index) 210848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 210948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos uvec3 expected = IndexTo3DCoord(index - 3 * kBufferSize, local_size.x() * num_groups.x(), 211048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos local_size.y() * num_groups.y()); 211148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos expected.x() %= local_size.x(); 211248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos expected.y() %= local_size.y(); 211348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos expected.z() %= local_size.z(); 211448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!IsEqual(data[index], uvec4(expected.x(), expected.y(), expected.z(), 0))) 211548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 2116910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() 2117910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << tcu::TestLog::Message << "gl_LocalInvocationID: Invalid data at index " << index << "." 2118910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << tcu::TestLog::EndMessage; 211948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return false; 212048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 212148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 212248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos // gl_GlobalInvocationID 212348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLuint index = 4 * kBufferSize; index < 5 * kBufferSize; ++index) 212448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 212548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos uvec3 expected = IndexTo3DCoord(index - 4 * kBufferSize, local_size.x() * num_groups.x(), 212648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos local_size.y() * num_groups.y()); 212748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!IsEqual(data[index], uvec4(expected.x(), expected.y(), expected.z(), 0))) 212848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 2129910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() 2130910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << tcu::TestLog::Message << "gl_GlobalInvocationID: Invalid data at index " << index << "." 2131910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << tcu::TestLog::EndMessage; 213248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return false; 213348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 213448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 213548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos // gl_LocalInvocationIndex 213648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLuint index = 5 * kBufferSize; index < 6 * kBufferSize; ++index) 213748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 213848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos uvec3 coord = IndexTo3DCoord(index - 5 * kBufferSize, local_size.x() * num_groups.x(), 213948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos local_size.y() * num_groups.y()); 214048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLuint expected = (coord.x() % local_size.x()) + (coord.y() % local_size.y()) * local_size.x() + 214148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos (coord.z() % local_size.z()) * local_size.x() * local_size.y(); 214248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!IsEqual(data[index], uvec4(expected))) 214348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 2144910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() 2145910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << tcu::TestLog::Message << "gl_LocalInvocationIndex: Invalid data at index " << index << "." 2146910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << tcu::TestLog::EndMessage; 214748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return false; 214848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 214948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 215048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return true; 215148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 215248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 215348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Setup() 215448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 215548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_program = 0; 215648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_storage_buffer = 0; 215748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_dispatch_buffer = 0; 215848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 215948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 216048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 216148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Run() 216248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 216348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!RunIteration(uvec3(64, 1, 1), uvec3(8, 1, 1), false)) 216448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 216548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!RunIteration(uvec3(1, 1, 64), uvec3(1, 5, 2), true)) 216648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 216748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!RunIteration(uvec3(1, 1, 4), uvec3(2, 2, 2), false)) 216848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 216948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!RunIteration(uvec3(3, 2, 1), uvec3(1, 2, 3), true)) 217048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 217148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!RunIteration(uvec3(2, 4, 2), uvec3(2, 4, 1), false)) 217248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 217348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!RunIteration(uvec3(2, 4, 7), uvec3(2, 1, 4), true)) 217448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 217548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 217648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 217748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 217848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Cleanup() 217948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 218048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUseProgram(0); 218148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteProgram(m_program); 218248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteBuffers(1, &m_storage_buffer); 218348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteBuffers(1, &m_dispatch_buffer); 218448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 218548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 218648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}; 218748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 218848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosclass BasicMax : public ComputeShaderBase 218948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 219048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 219148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Title() 219248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 219348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "CS max values"; 219448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 219548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 219648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Purpose() 219748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 219848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "Verify (on the API and GLSL side) that all GL_MAX_COMPUTE_* values are not less than" NL 219948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "required by the OpenGL specification."; 220048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 220148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 220248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Method() 220348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 220448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "1. Use all API commands to query all GL_MAX_COMPUTE_* values. Verify that they are correct." NL 220548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "2. Verify all gl_MaxCompute* constants in the GLSL."; 220648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 220748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 220848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string PassCriteria() 220948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 221048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "Everything works as expected."; 221148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 221248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 221348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_program; 221448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_buffer; 221548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 221648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos bool CheckIndexed(GLenum target, const GLint* min_values) 221748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 221848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLint i; 221948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLint64 i64; 222048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLfloat f; 222148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLdouble d; 222248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLboolean b; 222348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 222448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLuint c = 0; c < 3; c++) 222548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 222648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetIntegeri_v(target, c, &i); 222748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (i < min_values[c]) 222848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 2229910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() << tcu::TestLog::Message << "Is " << i << " should be at least " 2230910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << min_values[c] << "." << tcu::TestLog::EndMessage; 223148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return false; 223248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 223348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 223448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLuint c = 0; c < 3; c++) 223548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 223648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetInteger64i_v(target, c, &i64); 223748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (i64 < static_cast<GLint64>(min_values[c])) 223848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 2239910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() 2240910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << tcu::TestLog::Message << "Is " << static_cast<GLint>(i64) << " should be at least " 2241910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << min_values[c] << "." << tcu::TestLog::EndMessage; 224248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return false; 224348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 224448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 224548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLuint c = 0; c < 3; c++) 224648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 224748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetFloati_v(target, c, &f); 224848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (f < static_cast<GLfloat>(min_values[c])) 224948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 2250910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() 2251910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << tcu::TestLog::Message << "Is " << static_cast<GLint>(f) << " should be at least " 2252910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << min_values[c] << "." << tcu::TestLog::EndMessage; 225348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return false; 225448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 225548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 225648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLuint c = 0; c < 3; c++) 225748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 225848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetDoublei_v(target, c, &d); 225948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (d < static_cast<GLdouble>(min_values[c])) 226048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 2261910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() 2262910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << tcu::TestLog::Message << "Is " << static_cast<GLint>(d) << " should be at least " 2263910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << min_values[c] << "." << tcu::TestLog::EndMessage; 226448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return false; 226548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 226648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 226748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLuint c = 0; c < 3; c++) 226848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 226948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetBooleani_v(target, c, &b); 227048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (b == GL_FALSE) 227148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 2272910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() 2273910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << tcu::TestLog::Message << "Is GL_FALSE should be at least GL_TRUE." << tcu::TestLog::EndMessage; 227448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return false; 227548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 227648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 227748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 227848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return true; 227948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 228048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 228148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos bool Check(GLenum target, const GLint min_value) 228248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 228348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLint i; 228448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLint64 i64; 228548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLfloat f; 228648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLdouble d; 228748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLboolean b; 228848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 228948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetIntegerv(target, &i); 229048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (i < min_value) 229148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 2292910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() << tcu::TestLog::Message << "Is " << i << " should be at least " 2293910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << min_value << "." << tcu::TestLog::EndMessage; 229448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return false; 229548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 229648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetInteger64v(target, &i64); 229748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (static_cast<GLint>(i64) < min_value) 229848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 2299910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() 2300910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << tcu::TestLog::Message << "Is " << static_cast<GLint>(i64) << " should be at least " << min_value 2301910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << "." << tcu::TestLog::EndMessage; 230248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return false; 230348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 230448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetFloatv(target, &f); 230548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (f < static_cast<GLfloat>(min_value)) 230648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 2307910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() 2308910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << tcu::TestLog::Message << "Is " << static_cast<GLint>(f) << " should be at least " << min_value << "." 2309910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << tcu::TestLog::EndMessage; 231048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return false; 231148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 231248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetDoublev(target, &d); 231348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (d < static_cast<GLdouble>(min_value)) 231448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 2315910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() 2316910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << tcu::TestLog::Message << "Is " << static_cast<GLint>(d) << " should be at least " << min_value << "." 2317910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << tcu::TestLog::EndMessage; 231848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return false; 231948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 232048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetBooleanv(target, &b); 232148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (b != (min_value ? GL_TRUE : GL_FALSE)) 232248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 2323910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() << tcu::TestLog::Message << "Is " << b << " should be " 2324910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << (min_value ? GL_TRUE : GL_FALSE) << "." << tcu::TestLog::EndMessage; 232548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return false; 232648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 232748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 232848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return true; 232948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 233048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 233148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Setup() 233248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 233348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_program = 0; 233448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_buffer = 0; 233548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 233648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 233748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 233848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Run() 233948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 234048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLint work_group_count[3] = { 65535, 65535, 65535 }; 234148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!CheckIndexed(GL_MAX_COMPUTE_WORK_GROUP_COUNT, work_group_count)) 234248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 234348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 234448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLint work_group_size[3] = { 1024, 1024, 64 }; 234548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!CheckIndexed(GL_MAX_COMPUTE_WORK_GROUP_SIZE, work_group_size)) 234648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 234748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 234848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!Check(GL_MAX_COMPUTE_UNIFORM_BLOCKS, 12)) 234948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 235048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!Check(GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS, 16)) 235148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 235248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!Check(GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS, 8)) 235348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 235448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!Check(GL_MAX_COMPUTE_ATOMIC_COUNTERS, 8)) 235548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 235648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!Check(GL_MAX_COMPUTE_SHARED_MEMORY_SIZE, 32768)) 235748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 235848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 235948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5))) 236048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 236148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!Check(GL_MAX_COMPUTE_UNIFORM_COMPONENTS, 1024)) 236248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 236348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 236448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else 236548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 236648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!Check(GL_MAX_COMPUTE_UNIFORM_COMPONENTS, 512)) 236748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 236848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 236948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 237048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!Check(GL_MAX_COMPUTE_IMAGE_UNIFORMS, 8)) 237148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 237248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!Check(GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS, 512)) 237348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 237448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 237548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* const glsl_cs = 237648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos NL "layout(local_size_x = 1) in;" NL "layout(std430) buffer Output {" NL " int g_output;" NL "};" NL 237748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "uniform ivec3 MaxComputeWorkGroupCount;" NL "uniform ivec3 MaxComputeWorkGroupSize;" NL 237848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "uniform int MaxComputeUniformComponents;" NL "uniform int MaxComputeTextureImageUnits;" NL 237948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "uniform int MaxComputeImageUniforms;" NL "uniform int MaxComputeAtomicCounters;" NL 238048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "uniform int MaxComputeAtomicCounterBuffers;" NL "void main() {" NL " g_output = 1;" NL 238148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " if (MaxComputeWorkGroupCount != gl_MaxComputeWorkGroupCount) g_output = 0;" NL 238248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " if (MaxComputeWorkGroupSize != gl_MaxComputeWorkGroupSize) g_output = 0;" NL 238348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " if (MaxComputeUniformComponents != gl_MaxComputeUniformComponents) g_output = 0;" NL 238448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " if (MaxComputeTextureImageUnits != gl_MaxComputeTextureImageUnits) g_output = 0;" NL 238548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " if (MaxComputeImageUniforms != gl_MaxComputeImageUniforms) g_output = 0;" NL 238648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " if (MaxComputeAtomicCounters != gl_MaxComputeAtomicCounters) g_output = 0;" NL 238748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " if (MaxComputeAtomicCounterBuffers != gl_MaxComputeAtomicCounterBuffers) g_output = 0;" NL "}"; 238848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_program = CreateComputeProgram(glsl_cs); 238948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glLinkProgram(m_program); 239048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!CheckProgram(m_program)) 239148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 239248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUseProgram(m_program); 239348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 239448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLint p[3]; 239548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_COUNT, 0, &p[0]); 239648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_COUNT, 1, &p[1]); 239748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_COUNT, 2, &p[2]); 239848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUniform3i(glGetUniformLocation(m_program, "MaxComputeWorkGroupCount"), p[0], p[1], p[2]); 239948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 240048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_SIZE, 0, &p[0]); 240148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_SIZE, 1, &p[1]); 240248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_SIZE, 2, &p[2]); 240348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUniform3iv(glGetUniformLocation(m_program, "MaxComputeWorkGroupSize"), 1, p); 240448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 240548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetIntegerv(GL_MAX_COMPUTE_UNIFORM_COMPONENTS, p); 240648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUniform1i(glGetUniformLocation(m_program, "MaxComputeUniformComponents"), p[0]); 240748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 240848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetIntegerv(GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS, p); 240948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUniform1iv(glGetUniformLocation(m_program, "MaxComputeTextureImageUnits"), 1, p); 241048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 241148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetIntegerv(GL_MAX_COMPUTE_IMAGE_UNIFORMS, p); 241248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUniform1i(glGetUniformLocation(m_program, "MaxComputeImageUniforms"), p[0]); 241348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 241448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetIntegerv(GL_MAX_COMPUTE_ATOMIC_COUNTERS, p); 241548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUniform1i(glGetUniformLocation(m_program, "MaxComputeAtomicCounters"), p[0]); 241648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 241748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetIntegerv(GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS, p); 241848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUniform1i(glGetUniformLocation(m_program, "MaxComputeAtomicCounterBuffers"), p[0]); 241948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 242048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLint data = 0xffff; 242148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGenBuffers(1, &m_buffer); 242248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_buffer); 242348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(GLint), &data, GL_DYNAMIC_DRAW); 242448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 242548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDispatchCompute(1, 1, 1); 242648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 242748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT); 242848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, sizeof(GLint), &data); 242948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 243048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return data == 1 ? NO_ERROR : ERROR; 243148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 243248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Cleanup() 243348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 243448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUseProgram(0); 243548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteProgram(m_program); 243648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteBuffers(1, &m_buffer); 243748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 243848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 243948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}; 244048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 244148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosclass BasicBuildMonolithic : public ComputeShaderBase 244248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 244348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 244448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Title() 244548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 244648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return "Building CS monolithic program"; 244748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 244848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 244948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Purpose() 245048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 245148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "1. Verify that building monolithic CS program works as expected." NL 245248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "2. Verify that program consisting from 3 compilation units links as expected." NL 245348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "3. Verify that CS consisting from 2 strings compiles as expected."; 245448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 245548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 245648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Method() 245748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 245848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "1. Create, compile and link CS using CreateShader, CompileShader and LinkProgram commands." NL 245948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "2. Dispatch and verify CS program."; 246048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 246148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 246248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string PassCriteria() 246348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 246448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return "Everything works as expected."; 246548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 246648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 246748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Run() 246848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 246948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* const cs1[2] = { "#version 430 core", 247048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 247148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos NL "layout(local_size_x = 1) in;" NL "void Run();" NL "void main() {" NL 247248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " Run();" NL "}" }; 247348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 247448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* const cs2 = 247548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "#version 430 core" NL "layout(binding = 0, std430) buffer Output {" NL " vec4 g_output;" NL "};" NL 247648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "vec4 CalculateOutput();" NL "void Run() {" NL " g_output = CalculateOutput();" NL "}"; 247748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 247848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* const cs3 = 247948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "#version 430 core" NL "layout(local_size_x = 1) in;" NL "layout(binding = 0, std430) buffer Output {" NL 248048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " vec4 g_output;" NL "};" NL "vec4 CalculateOutput() {" NL " g_output = vec4(0);" NL 248148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " return vec4(1, 2, 3, 4);" NL "}"; 248248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 248348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLuint sh1 = glCreateShader(GL_COMPUTE_SHADER); 248448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 248548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLint type; 248648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetShaderiv(sh1, GL_SHADER_TYPE, &type); 248748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (static_cast<GLenum>(type) != GL_COMPUTE_SHADER) 248848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 2489910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() 2490910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << tcu::TestLog::Message << "SHADER_TYPE should be COMPUTE_SHADER." << tcu::TestLog::EndMessage; 249148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteShader(sh1); 249248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return false; 249348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 249448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 249548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glShaderSource(sh1, 2, cs1, NULL); 249648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glCompileShader(sh1); 249748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 249848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLuint sh2 = glCreateShader(GL_COMPUTE_SHADER); 249948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glShaderSource(sh2, 1, &cs2, NULL); 250048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glCompileShader(sh2); 250148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 250248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLuint sh3 = glCreateShader(GL_COMPUTE_SHADER); 250348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glShaderSource(sh3, 1, &cs3, NULL); 250448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glCompileShader(sh3); 250548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 250648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLuint p = glCreateProgram(); 250748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glAttachShader(p, sh1); 250848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glAttachShader(p, sh2); 250948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glAttachShader(p, sh3); 251048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glLinkProgram(p); 251148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 251248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteShader(sh1); 251348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteShader(sh2); 251448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteShader(sh3); 251548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 251648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos bool res = CheckProgram(p); 251748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 251848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint buffer; 251948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGenBuffers(1, &buffer); 252048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, buffer); 252148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(vec4), &vec4(0.0f)[0], GL_DYNAMIC_DRAW); 252248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0); 252348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 252448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUseProgram(p); 252548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDispatchCompute(1, 1, 1); 252648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 252748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos vec4 data; 252848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBuffer(GL_SHADER_STORAGE_BUFFER, buffer); 252948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT); 253048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, sizeof(vec4), &data[0]); 253148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!IsEqual(data, vec4(1.0f, 2.0f, 3.0f, 4.0f))) 253248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 2533910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() 2534910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << tcu::TestLog::Message << "Invalid value!" << tcu::TestLog::EndMessage; 253548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos res = false; 253648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 253748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 253848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteBuffers(1, &buffer); 253948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUseProgram(0); 254048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteProgram(p); 254148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 254248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return res == true ? NO_ERROR : ERROR; 254348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 254448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}; 254548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 254648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosclass BasicBuildSeparable : public ComputeShaderBase 254748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 254848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 254948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Title() 255048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 255148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return "Building CS separable program"; 255248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 255348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 255448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Purpose() 255548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 255648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "1. Verify that building separable CS program works as expected." NL 255748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "2. Verify that program consisting from 4 strings works as expected."; 255848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 255948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 256048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Method() 256148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 256248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "1. Create, compile and link CS using CreateShaderProgramv command." NL 256348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "2. Dispatch and verify CS program."; 256448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 256548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 256648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string PassCriteria() 256748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 256848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return "Everything works as expected."; 256948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 257048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 257148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Run() 257248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 257348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* const cs[4] = { 257448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "#version 430 core", 257548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 257648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos NL "layout(local_size_x = 1) in;" NL "void Run();" NL "void main() {" NL " Run();" NL "}", 257748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos NL "layout(binding = 0, std430) buffer Output {" NL " vec4 g_output;" NL "};" NL 257848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "vec4 CalculateOutput();" NL "void Run() {" NL " g_output = CalculateOutput();" NL "}", 257948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos NL "vec4 CalculateOutput() {" NL " g_output = vec4(0);" NL " return vec4(1, 2, 3, 4);" NL "}" 258048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos }; 258148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 258248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLuint p = glCreateShaderProgramv(GL_COMPUTE_SHADER, 4, cs); 258348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos bool res = CheckProgram(p); 258448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 258548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint buffer; 258648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGenBuffers(1, &buffer); 258748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, buffer); 258848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(vec4), &vec4(0.0f)[0], GL_DYNAMIC_DRAW); 258948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0); 259048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 259148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUseProgram(p); 259248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDispatchCompute(1, 1, 1); 259348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 259448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos vec4 data; 259548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBuffer(GL_SHADER_STORAGE_BUFFER, buffer); 259648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT); 259748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, sizeof(vec4), &data[0]); 259848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!IsEqual(data, vec4(1.0f, 2.0f, 3.0f, 4.0f))) 259948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 2600910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() 2601910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << tcu::TestLog::Message << "Invalid value!" << tcu::TestLog::EndMessage; 260248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos res = false; 260348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 260448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 260548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, sizeof(vec4), &vec4(0.0f)[0]); 260648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 260748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint pipeline; 260848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGenProgramPipelines(1, &pipeline); 260948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUseProgramStages(pipeline, GL_COMPUTE_SHADER_BIT, p); 261048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 261148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUseProgram(0); 261248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindProgramPipeline(pipeline); 261348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDispatchCompute(1, 1, 1); 261448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 261548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT); 261648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, sizeof(vec4), &data[0]); 261748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!IsEqual(data, vec4(1.0f, 2.0f, 3.0f, 4.0f))) 261848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 2619910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() 2620910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << tcu::TestLog::Message << "Invalid value!" << tcu::TestLog::EndMessage; 262148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos res = false; 262248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 262348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 262448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteProgramPipelines(1, &pipeline); 262548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteBuffers(1, &buffer); 262648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteProgram(p); 262748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 262848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return res == true ? NO_ERROR : ERROR; 262948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 263048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}; 263148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 263248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosclass BasicSharedSimple : public ComputeShaderBase 263348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 263448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Title() 263548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 263648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return "Shared Memory - simple usage"; 263748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 263848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 263948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Purpose() 264048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 264148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "1. Verify that shared array of uints works as expected." NL 264248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "2. Verify that shared memory written by one invocation is observable by other invocations" NL 264348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " when groupMemoryBarrier() and barrier() built-in functions are used."; 264448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 264548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 264648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Method() 264748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 264848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "1. Create and dispatch CS with DispatchCompute and DispatchComputeIndirect commands." NL 264948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "2. Verify results written by CS to SSBO." NL 265048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "3. Repeat for several different number of work groups."; 265148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 265248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 265348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string PassCriteria() 265448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 265548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return "Everything works as expected."; 265648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 265748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 265848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_program; 265948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_storage_buffer; 266048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_dispatch_buffer; 266148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 266248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos bool RunIteration(const GLuint num_groups, bool dispatch_indirect) 266348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 266448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLuint kBufferSize = 256 * num_groups; 266548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 266648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::vector<GLuint> data(kBufferSize, 0xffff); 266748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_storage_buffer == 0) 266848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGenBuffers(1, &m_storage_buffer); 266948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_storage_buffer); 267048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(GLuint) * kBufferSize, &data[0], GL_DYNAMIC_DRAW); 267148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0); 267248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 267348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUseProgram(m_program); 267448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (dispatch_indirect) 267548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 267648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLuint groups[3] = { num_groups, 1, 1 }; 267748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_dispatch_buffer == 0) 267848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGenBuffers(1, &m_dispatch_buffer); 267948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBuffer(GL_DISPATCH_INDIRECT_BUFFER, m_dispatch_buffer); 268048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBufferData(GL_DISPATCH_INDIRECT_BUFFER, sizeof(groups), groups, GL_STATIC_DRAW); 268148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDispatchComputeIndirect(0); 268248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 268348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else 268448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 268548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDispatchCompute(num_groups, 1, 1); 268648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 268748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 268848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer); 268948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT); 269048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, sizeof(GLuint) * kBufferSize, &data[0]); 269148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLuint i = 0; i < kBufferSize; ++i) 269248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 269348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (data[i] != 1) 269448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 2695910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() << tcu::TestLog::Message << "Data at index " << i << " is " 2696910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << data[i] << " should be 1." << tcu::TestLog::EndMessage; 269748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return false; 269848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 269948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 270048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return true; 270148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 270248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 270348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Setup() 270448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 270548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_program = 0; 270648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_storage_buffer = 0; 270748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_dispatch_buffer = 0; 270848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 270948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 271048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 271148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Run() 271248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 271348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* const glsl_cs = 271448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos NL "layout(local_size_x = 256) in;" NL "layout(std430) buffer Output {" NL " uint g_output[];" NL "};" NL 271548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "shared uint g_shared_data[256];" NL "void main() {" NL 271648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " g_shared_data[gl_LocalInvocationID.x] = gl_LocalInvocationIndex;" NL 271748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " groupMemoryBarrier();" // flush memory stores 271848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos NL " barrier();" // wait for all stores to finish 271948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos NL " g_output[gl_GlobalInvocationID.x] = 1;" NL " if (gl_LocalInvocationIndex < 255) {" NL 272048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " const uint res = g_shared_data[gl_LocalInvocationID.x + " 272148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "1];" // load data from shared memory filled by other thread 272248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos NL " if (res != (gl_LocalInvocationIndex + 1)) {" NL " g_output[gl_GlobalInvocationID.x] = 0;" NL 272348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " }" NL " }" NL "}"; 272448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_program = CreateComputeProgram(glsl_cs); 272548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glLinkProgram(m_program); 272648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!CheckProgram(m_program)) 272748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 272848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 272948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!RunIteration(1, false)) 273048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 273148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!RunIteration(8, true)) 273248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 273348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!RunIteration(13, false)) 273448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 273548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!RunIteration(7, true)) 273648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 273748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 273848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 273948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Cleanup() 274048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 274148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUseProgram(0); 274248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteProgram(m_program); 274348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteBuffers(1, &m_storage_buffer); 274448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteBuffers(1, &m_dispatch_buffer); 274548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 274648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 274748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}; 274848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 274948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosclass BasicSharedStruct : public ComputeShaderBase 275048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 275148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Title() 275248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 275348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return "Shared Memory - arrays and structers"; 275448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 275548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 275648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Purpose() 275748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 275848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "1. Verify that vectors, matrices, structers and arrays of those can be used" NL 275948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " as a shared memory." NL 276048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "2. Verify that shared memory can be indexed with constant values, built-in" NL 276148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " variables and dynamic expressions." NL 276248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "3. Verify that memoryBarrierAtomicCounter(), memoryBarrierImage(), memoryBarrier()," NL 276348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " memoryBarrierBuffer() and memoryBarrierShared() built-in functions are accepted" NL 276448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " by the GLSL compiler."; 276548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 276648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 276748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Method() 276848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 276948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "1. Create and dispatch CS with DispatchCompute and DispatchComputeIndirect commands." NL 277048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "2. Verify results written by CS to SSBO."; 277148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 277248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 277348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string PassCriteria() 277448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 277548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return "Everything works as expected."; 277648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 277748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 277848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_program; 277948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_storage_buffer; 278048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_dispatch_buffer; 278148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 278248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos bool RunIteration(bool dispatch_indirect) 278348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 278448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLuint kBufferSize = 256; 278548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 278648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::vector<vec4> data(kBufferSize); 278748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_storage_buffer == 0) 278848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGenBuffers(1, &m_storage_buffer); 278948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_storage_buffer); 279048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(vec4) * kBufferSize, &data[0], GL_DYNAMIC_DRAW); 279148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0); 279248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 279348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUseProgram(m_program); 279448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (dispatch_indirect) 279548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 279648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLuint groups[3] = { 1, 1, 1 }; 279748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_dispatch_buffer == 0) 279848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGenBuffers(1, &m_dispatch_buffer); 279948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBuffer(GL_DISPATCH_INDIRECT_BUFFER, m_dispatch_buffer); 280048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBufferData(GL_DISPATCH_INDIRECT_BUFFER, sizeof(groups), groups, GL_STATIC_DRAW); 280148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDispatchComputeIndirect(0); 280248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 280348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else 280448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 280548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDispatchCompute(1, 1, 1); 280648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 280748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 280848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer); 280948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT); 281048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, sizeof(vec4) * kBufferSize, &data[0]); 281148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLuint i = 0; i < kBufferSize; ++i) 281248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 281348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!IsEqual(data[i], vec4(static_cast<float>(i)))) 281448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 2815910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() 2816910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << tcu::TestLog::Message << "Invalid data at index " << i << "." << tcu::TestLog::EndMessage; 281748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return false; 281848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 281948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 282048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return true; 282148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 282248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 282348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Setup() 282448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 282548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_program = 0; 282648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_storage_buffer = 0; 282748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_dispatch_buffer = 0; 282848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 282948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 283048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 283148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Run() 283248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 283348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* const glsl_cs = NL 283448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "layout(local_size_x = 128) in;" NL "layout(std430) buffer Output {" NL " vec4 g_output[256];" NL "};" NL 283548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "struct SubData {" NL " mat2x4 data;" NL "};" NL "struct Data {" NL " uint index;" NL " vec3 data0;" NL 283648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " SubData data1;" NL "};" NL "shared Data g_shared_data[256];" NL "shared int g_shared_buf[2];" NL 283748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void main() {" NL " if (gl_LocalInvocationID.x == 0) {" NL " g_shared_buf[1] = 1;" NL 283848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " g_shared_buf[1 + gl_LocalInvocationID.x] = 0;" NL " g_shared_buf[0] = 128;" NL 283948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " g_output[0] = vec4(g_shared_buf[1]);" NL " g_output[128] = vec4(g_shared_buf[0]);" NL 284048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " memoryBarrierBuffer();" // note: this call is not needed here, just check if compiler accepts it 284148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos NL " } else {" NL " const uint index = gl_LocalInvocationIndex;" NL 284248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " g_shared_data[index].index = index;" NL " g_shared_data[index + 128].index = index + 128;" NL 284348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " g_shared_data[index].data1.data = mat2x4(0.0);" NL 284448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " g_shared_data[index + 128].data1.data = mat2x4(0.0);" NL 284548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " g_output[index] = vec4(g_shared_data[index].index);" // load data from shared memory 284648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos NL " g_output[index + 128] = vec4(g_shared_data[index + 128].index);" NL 284748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " memoryBarrierShared();" // note: this call is not needed here, just check if compiler accepts it 284848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos NL " }" NL " memoryBarrierAtomicCounter();" NL " memoryBarrierImage();" NL 284948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " memoryBarrier();" // note: these calls are not needed here, just check if compiler accepts them 285048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos NL "}"; 285148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_program = CreateComputeProgram(glsl_cs); 285248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glLinkProgram(m_program); 285348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!CheckProgram(m_program)) 285448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 285548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 285648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!RunIteration(false)) 285748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 285848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!RunIteration(true)) 285948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 286048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 286148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 286248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 286348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Cleanup() 286448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 286548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUseProgram(0); 286648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteProgram(m_program); 286748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteBuffers(1, &m_storage_buffer); 286848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteBuffers(1, &m_dispatch_buffer); 286948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 287048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 287148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}; 287248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 287348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosclass BasicDispatchIndirect : public ComputeShaderBase 287448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 287548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Title() 287648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 287748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "DispatchComputeIndirect command"; 287848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 287948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 288048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Purpose() 288148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 288248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL 288348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "1. Verify that DispatchComputeIndirect command works as described in the OpenGL specification." NL 288448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "2. Verify that <offset> parameter is correctly applied." NL 288548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "3. Verify that updating dispatch buffer with different methods (BufferData, BufferSubData, MapBuffer)" NL 288648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " just before DispatchComputeIndirect call works as expected." NL 288748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "4. Verify that GL_DISPATCH_INDIRECT_BUFFER_BINDING binding point is set correctly."; 288848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 288948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 289048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Method() 289148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 289248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL 289348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "1. Create CS and dispatch indirect buffer." NL "2. Dispatch CS with DispatchComputeIndirect command." NL 289448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "3. Update dispatch indirect buffer." NL 289548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "4. Repeat several times updating dispatch buffer with different methods and changing <offset> parameter."; 289648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 289748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 289848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string PassCriteria() 289948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 290048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "Everything works as expected."; 290148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 290248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 290348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_program; 290448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_storage_buffer; 290548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_dispatch_buffer[2]; 290648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 290748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos bool RunIteration(GLintptr offset, GLuint buffer_size) 290848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 290948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::vector<GLuint> data(buffer_size); 291048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_storage_buffer == 0) 291148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGenBuffers(1, &m_storage_buffer); 291248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_storage_buffer); 291348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(GLuint) * buffer_size, &data[0], GL_DYNAMIC_DRAW); 291448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 291548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDispatchComputeIndirect(offset); 291648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 291748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT); 291848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, sizeof(GLuint) * buffer_size, &data[0]); 291948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLuint i = 0; i < buffer_size; ++i) 292048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 292148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (data[i] != i) 292248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 2923910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() << tcu::TestLog::Message << "Data at index " << i << " is " 2924910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << data[i] << " should be " << i << "." << tcu::TestLog::EndMessage; 292548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return false; 292648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 292748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 292848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return true; 292948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 293048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 293148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos bool CheckBinding(GLuint expected) 293248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 293348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLint i; 293448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLint64 i64; 293548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLfloat f; 293648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLdouble d; 293748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLboolean b; 293848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 293948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetIntegerv(GL_DISPATCH_INDIRECT_BUFFER_BINDING, &i); 294048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (static_cast<GLuint>(i) != expected) 294148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 294248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return false; 294348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 294448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetInteger64v(GL_DISPATCH_INDIRECT_BUFFER_BINDING, &i64); 294548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (static_cast<GLuint>(i64) != expected) 294648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 294748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return false; 294848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 294948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetFloatv(GL_DISPATCH_INDIRECT_BUFFER_BINDING, &f); 295048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (static_cast<GLuint>(f) != expected) 295148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 295248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return false; 295348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 295448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetDoublev(GL_DISPATCH_INDIRECT_BUFFER_BINDING, &d); 295548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (static_cast<GLuint>(d) != expected) 295648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 295748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return false; 295848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 295948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetBooleanv(GL_DISPATCH_INDIRECT_BUFFER_BINDING, &b); 296048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (b != (expected != 0 ? GL_TRUE : GL_FALSE)) 296148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 296248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return false; 296348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 296448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 296548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return true; 296648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 296748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 296848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Setup() 296948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 297048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_program = 0; 297148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_storage_buffer = 0; 297248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos memset(m_dispatch_buffer, 0, sizeof(m_dispatch_buffer)); 297348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 297448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 297548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 297648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Run() 297748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 297848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* const glsl_cs = 297948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos NL "layout(local_size_x = 1) in;" NL "layout(std430) buffer Output {" NL " uint g_output[];" NL "};" NL 298048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "uniform uvec3 g_global_size;" NL "void main() {" NL 298148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " const uint global_index = gl_GlobalInvocationID.x +" NL 298248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " gl_GlobalInvocationID.y * g_global_size.x +" NL 298348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " gl_GlobalInvocationID.z * g_global_size.x * g_global_size.y;" NL 298448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " if (gl_NumWorkGroups != g_global_size) {" NL " g_output[global_index] = 0xffff;" NL 298548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " return;" NL " }" NL " g_output[global_index] = global_index;" NL "}"; 298648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_program = CreateComputeProgram(glsl_cs); 298748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glLinkProgram(m_program); 298848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!CheckProgram(m_program)) 298948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 299048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 299148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!CheckBinding(0)) 299248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 299348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 299448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGenBuffers(2, m_dispatch_buffer); 299548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 299648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLuint data[] = { 1, 2, 3, 4, 5, 6, 7, 8 }; 299748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLuint data2[] = { 3, 1, 4, 4 }; 299848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 299948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBuffer(GL_DISPATCH_INDIRECT_BUFFER, m_dispatch_buffer[0]); 300048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBufferData(GL_DISPATCH_INDIRECT_BUFFER, sizeof(data), data, GL_STREAM_DRAW); 300148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!CheckBinding(m_dispatch_buffer[0])) 300248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 300348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 300448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBuffer(GL_DISPATCH_INDIRECT_BUFFER, m_dispatch_buffer[1]); 300548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBufferData(GL_DISPATCH_INDIRECT_BUFFER, sizeof(data2), data2, GL_STREAM_READ); 300648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!CheckBinding(m_dispatch_buffer[1])) 300748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 300848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 300948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUseProgram(m_program); 301048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBuffer(GL_DISPATCH_INDIRECT_BUFFER, m_dispatch_buffer[0]); 301148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 301248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUniform3ui(glGetUniformLocation(m_program, "g_global_size"), 1, 2, 3); 301348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!RunIteration(0, 6)) 301448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 301548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 301648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUniform3ui(glGetUniformLocation(m_program, "g_global_size"), 2, 3, 4); 301748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!RunIteration(4, 24)) 301848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 301948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 302048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUniform3ui(glGetUniformLocation(m_program, "g_global_size"), 4, 5, 6); 302148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!RunIteration(12, 120)) 302248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 302348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 302448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBufferSubData(GL_DISPATCH_INDIRECT_BUFFER, 20, 12, data); 302548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUniform3ui(glGetUniformLocation(m_program, "g_global_size"), 1, 2, 3); 302648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!RunIteration(20, 6)) 302748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 302848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 302948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint* ptr = static_cast<GLuint*>(glMapBuffer(GL_DISPATCH_INDIRECT_BUFFER, GL_WRITE_ONLY)); 303048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *ptr++ = 4; 303148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *ptr++ = 4; 303248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *ptr++ = 4; 303348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUnmapBuffer(GL_DISPATCH_INDIRECT_BUFFER); 303448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 303548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUniform3ui(glGetUniformLocation(m_program, "g_global_size"), 4, 4, 4); 303648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!RunIteration(0, 64)) 303748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 303848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 303948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBuffer(GL_DISPATCH_INDIRECT_BUFFER, m_dispatch_buffer[1]); 304048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 304148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUniform3ui(glGetUniformLocation(m_program, "g_global_size"), 1, 4, 4); 304248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!RunIteration(4, 16)) 304348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 304448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 304548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteBuffers(2, m_dispatch_buffer); 304648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos memset(m_dispatch_buffer, 0, sizeof(m_dispatch_buffer)); 304748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 304848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!CheckBinding(0)) 304948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 305048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 305148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 305248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 305348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Cleanup() 305448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 305548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUseProgram(0); 305648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteProgram(m_program); 305748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteBuffers(1, &m_storage_buffer); 305848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteBuffers(2, m_dispatch_buffer); 305948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 306048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 306148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}; 306248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 306348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosclass BasicSSOComputePipeline : public ComputeShaderBase 306448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 306548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Title() 306648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 306748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "Separable CS Programs - Compute and non-compute stages (1)"; 306848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 306948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Purpose() 307048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 307148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "1. Verify that compute and non-compute stages can be attached to one pipeline object." NL 307248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "2. Verify that DrawArrays and ComputeDispatch commands works as expected in this case."; 307348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 307448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Method() 307548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 307648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "1. Create VS, FS and CS. Attach all created stages to one pipeline object." NL 307748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "2. Bind pipeline object." NL "3. Invoke compute stage with DispatchCompute commmand." NL 307848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "4. Issue MemoryBarrier command." NL 307948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "5. Issue DrawArrays command which uses data written by the compute stage." NL "6. Verify result."; 308048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 308148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string PassCriteria() 308248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 308348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "Everything works as expected."; 308448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 308548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 308648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_vsp, m_fsp, m_csp; 308748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_storage_buffer; 308848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_vertex_array; 308948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_pipeline; 309048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 309148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Setup() 309248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 309348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_vsp = m_fsp = m_csp = 0; 309448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_storage_buffer = 0; 309548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_vertex_array = 0; 309648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_pipeline = 0; 309748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 309848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 309948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Run() 310048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 310148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* const glsl_cs = 310248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos NL "layout(local_size_x = 4) in;" NL "layout(std430) buffer Output {" NL " vec4 g_output[4];" NL "};" NL 310348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void main() {" NL " const vec2 quad[4] = { vec2(-1, -1), vec2(1, -1), vec2(-1, 1), vec2(1, 1) };" NL 310448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " g_output[gl_GlobalInvocationID.x] = vec4(quad[gl_GlobalInvocationID.x], 0, 1);" NL "}"; 310548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 310648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_csp = CreateComputeProgram(glsl_cs); 310748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glProgramParameteri(m_csp, GL_PROGRAM_SEPARABLE, GL_TRUE); 310848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glLinkProgram(m_csp); 310948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!CheckProgram(m_csp)) 311048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 311148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 311248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* const glsl_vs = 311348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos NL "layout(location = 0) in vec4 i_position;" NL "out gl_PerVertex {" NL " vec4 gl_Position;" NL "};" NL 311448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void main() {" NL " gl_Position = i_position;" NL "}"; 311548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_vsp = BuildShaderProgram(GL_VERTEX_SHADER, glsl_vs); 311648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!CheckProgram(m_vsp)) 311748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 311848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 311948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* const glsl_fs = 312048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos NL "layout(location = 0) out vec4 o_color;" NL "void main() {" NL " o_color = vec4(0, 1, 0, 1);" NL "}"; 312148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_fsp = BuildShaderProgram(GL_FRAGMENT_SHADER, glsl_fs); 312248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!CheckProgram(m_fsp)) 312348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 312448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 312548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGenProgramPipelines(1, &m_pipeline); 312648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUseProgramStages(m_pipeline, GL_VERTEX_SHADER_BIT, m_vsp); 312748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUseProgramStages(m_pipeline, GL_FRAGMENT_SHADER_BIT, m_fsp); 312848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUseProgramStages(m_pipeline, GL_COMPUTE_SHADER_BIT, m_csp); 312948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 313048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGenBuffers(1, &m_storage_buffer); 313148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer); 313248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(vec4) * 4, NULL, GL_DYNAMIC_DRAW); 313348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0); 313448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 313548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGenVertexArrays(1, &m_vertex_array); 313648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindVertexArray(m_vertex_array); 313748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBuffer(GL_ARRAY_BUFFER, m_storage_buffer); 313848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0); 313948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBuffer(GL_ARRAY_BUFFER, 0); 314048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glEnableVertexAttribArray(0); 314148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindVertexArray(0); 314248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 314348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindProgramPipeline(m_pipeline); 314448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_storage_buffer); 314548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDispatchCompute(1, 1, 1); 314648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 314748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glClear(GL_COLOR_BUFFER_BIT); 314848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindVertexArray(m_vertex_array); 314948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glMemoryBarrier(GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT); 315048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); 315148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 315248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!ValidateReadBuffer(0, 0, getWindowWidth(), getWindowHeight(), vec4(0, 1, 0, 1))) 315348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 315448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 315548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 315648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 315748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Cleanup() 315848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 315948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteProgram(m_vsp); 316048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteProgram(m_fsp); 316148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteProgram(m_csp); 316248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteBuffers(1, &m_storage_buffer); 316348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteVertexArrays(1, &m_vertex_array); 316448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteProgramPipelines(1, &m_pipeline); 316548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 316648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 316748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}; 316848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 316948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosclass BasicSSOCase2 : public ComputeShaderBase 317048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 317148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Title() 317248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 317348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "Separable CS Programs - Compute and non-compute stages (2)"; 317448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 317548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Purpose() 317648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 317748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "1. Verify that data computed by the compute stage is visible to non-compute stage after " 317848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "MemoryBarrier command." NL "2. Verify that ProgramParameteri(program, GL_PROGRAM_SEPARABLE, " 317948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "GL_TRUE) command works correctly for CS." NL 318048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "3. Verify that gl_WorkGroupSize built-in variable is a contant and can be used as an array size."; 318148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 318248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Method() 318348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 318448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "1. Create VS, FS and CS. Attach all created stages to one pipeline object." NL 318548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "2. Bind pipeline object." NL "3. Invoke compute stage with DispatchCompute commmand." NL 318648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "4. Issue MemoryBarrier command." NL 318748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "5. Issue DrawArrays command which uses data written to the buffer object by the compute stage." NL 318848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "6. Verify result."; 318948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 319048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string PassCriteria() 319148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 319248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "Everything works as expected."; 319348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 319448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 319548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_program_ab; 319648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_program_c; 319748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_pipeline; 319848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_storage_buffer; 319948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_vao; 320048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 320148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Setup() 320248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 320348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_program_ab = 0; 320448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_program_c = 0; 320548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_pipeline = 0; 320648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_storage_buffer = 0; 320748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_vao = 0; 320848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 320948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 321048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Run() 321148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 321248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLint res; 321348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetIntegerv(GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS, &res); 321448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (res <= 0) 321548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 321648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos OutputNotSupported("GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS <= 0"); 321748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 321848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 321948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 322048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* const glsl_a = 322148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "#version 430 core" NL "layout(binding = 1, std430) buffer Input {" NL " vec2 g_input[4];" NL "};" NL 322248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "out StageData {" NL " vec3 color;" NL "} g_vs_out;" NL "out gl_PerVertex {" NL " vec4 gl_Position;" NL 322348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "};" NL "void main() {" NL " gl_Position = vec4(g_input[gl_VertexID], 0, 1);" NL 322448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " g_vs_out.color = vec3(0, 1, 0);" NL "}"; 322548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 322648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* const glsl_b = 322748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "#version 430 core" NL "in StageData {" NL " vec3 color;" NL "} g_fs_in;" NL 322848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "layout(location = 0) out vec4 g_color;" NL "void main() {" NL " g_color = vec4(g_fs_in.color, 1);" NL "}"; 322948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 323048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* const glsl_c = 323148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "#version 430 core" NL "layout(local_size_x = 4) in;" NL "layout(binding = 1, std430) buffer Output {" NL 323248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " vec2 g_output[gl_WorkGroupSize.x];" NL "};" NL "void main() {" NL 323348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " if (gl_GlobalInvocationID.x == 0) {" NL " g_output[0] = vec2(-0.8, -0.8);" NL 323448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " } else if (gl_GlobalInvocationID.x == 1) {" NL " g_output[1] = vec2(0.8, -0.8);" NL 323548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " } else if (gl_GlobalInvocationID.x == 2) {" NL " g_output[2] = vec2(-0.8, 0.8);" NL 323648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " } else if (gl_GlobalInvocationID.x == 3) {" NL " g_output[3] = vec2(0.8, 0.8);" NL " }" NL "}"; 323748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 323848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_program_ab = glCreateProgram(); 323948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint sh = glCreateShader(GL_VERTEX_SHADER); 324048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glAttachShader(m_program_ab, sh); 324148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteShader(sh); 324248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glShaderSource(sh, 1, &glsl_a, NULL); 324348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glCompileShader(sh); 324448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 324548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos sh = glCreateShader(GL_FRAGMENT_SHADER); 324648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glAttachShader(m_program_ab, sh); 324748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteShader(sh); 324848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glShaderSource(sh, 1, &glsl_b, NULL); 324948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glCompileShader(sh); 325048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 325148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glProgramParameteri(m_program_ab, GL_PROGRAM_SEPARABLE, GL_TRUE); 325248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glLinkProgram(m_program_ab); 325348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 325448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_program_c = glCreateShaderProgramv(GL_COMPUTE_SHADER, 1, &glsl_c); 325548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGenVertexArrays(1, &m_vao); 325648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGenProgramPipelines(1, &m_pipeline); 325748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUseProgramStages(m_pipeline, GL_ALL_SHADER_BITS, m_program_ab); 325848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUseProgramStages(m_pipeline, GL_COMPUTE_SHADER_BIT, m_program_c); 325948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 326048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGenBuffers(1, &m_storage_buffer); 326148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_storage_buffer); 326248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(vec2) * 4, NULL, GL_STREAM_DRAW); 326348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 326448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glClear(GL_COLOR_BUFFER_BIT); 326548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindProgramPipeline(m_pipeline); 326648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDispatchCompute(1, 1, 1); 326748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT); 326848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindVertexArray(m_vao); 326948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); 327048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 327148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (getWindowWidth() < 500 && 327248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos !ValidateReadBufferCenteredQuad(getWindowWidth(), getWindowHeight(), vec3(0, 1, 0))) 327348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 327448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 327548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 327648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 327748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 327848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Cleanup() 327948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 328048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteProgram(m_program_ab); 328148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteProgram(m_program_c); 328248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteProgramPipelines(1, &m_pipeline); 328348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteBuffers(1, &m_storage_buffer); 328448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteVertexArrays(1, &m_vao); 328548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 328648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 328748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}; 328848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 328948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosclass BasicSSOCase3 : public ComputeShaderBase 329048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 329148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Title() 329248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 329348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "Separable CS Programs - Compute stage"; 329448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 329548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Purpose() 329648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 329748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "Verify that compute shader stage selected with UseProgram command has precedence" NL 329848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "over compute shader stage selected with BindProgramPipeline command."; 329948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 330048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Method() 330148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 330248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "1. Create CS0 with CreateProgram command. Create CS1 with CreateShaderProgramv command." NL 330348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "2. Verify that CS program selected with UseProgram is dispatched even if there is active" NL 330448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " compute stage bound by BindProgramPipeline."; 330548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 330648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string PassCriteria() 330748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 330848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "Everything works as expected."; 330948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 331048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 331148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_program_a; 331248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_program_b; 331348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_pipeline; 331448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_storage_buffer; 331548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 331648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Setup() 331748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 331848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_program_a = 0; 331948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_program_b = 0; 332048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_pipeline = 0; 332148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_storage_buffer = 0; 332248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 332348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 332448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Run() 332548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 332648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* const glsl_a = 332748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "#version 430 core" NL "layout(local_size_x = 1) in;" NL "layout(binding = 3, std430) buffer Output {" NL 332848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " int g_output;" NL "};" NL "void main() {" NL " g_output = 1;" NL "}"; 332948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 333048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* const glsl_b = 333148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "#version 430 core" NL "layout(local_size_x = 1) in;" NL "layout(binding = 3, std430) buffer Output {" NL 333248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " int g_output;" NL "};" NL "void main() {" NL " g_output = 2;" NL "}"; 333348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 333448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* create program A */ 333548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 333648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_program_a = glCreateProgram(); 333748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint sh = glCreateShader(GL_COMPUTE_SHADER); 333848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glAttachShader(m_program_a, sh); 333948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteShader(sh); 334048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glShaderSource(sh, 1, &glsl_a, NULL); 334148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glCompileShader(sh); 334248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glProgramParameteri(m_program_a, GL_PROGRAM_SEPARABLE, GL_TRUE); 334348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glLinkProgram(m_program_a); 334448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 334548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_program_b = glCreateShaderProgramv(GL_COMPUTE_SHADER, 1, &glsl_b); 334648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 334748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* create storage buffer */ 334848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 334948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos int data = 0; 335048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGenBuffers(1, &m_storage_buffer); 335148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, m_storage_buffer); 335248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(int), &data, GL_STREAM_READ); 335348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 335448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 335548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGenProgramPipelines(1, &m_pipeline); 335648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUseProgramStages(m_pipeline, GL_ALL_SHADER_BITS, m_program_b); 335748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 335848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUseProgram(m_program_a); 335948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindProgramPipeline(m_pipeline); 336048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDispatchCompute(1, 1, 1); 336148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT); 336248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 336348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* validate */ 336448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 336548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos int data; 336648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, sizeof(int), &data); 336748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (data != 1) 336848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 3369910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() 3370910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << tcu::TestLog::Message << "Data is " << data << " should be 1." << tcu::TestLog::EndMessage; 337148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 337248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 337348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 337448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 337548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUseProgram(0); 337648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDispatchCompute(1, 1, 1); 337748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT); 337848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 337948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* validate */ 338048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 338148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos int data; 338248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, sizeof(int), &data); 338348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (data != 2) 338448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 3385910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() 3386910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << tcu::TestLog::Message << "Data is " << data << " should be 2." << tcu::TestLog::EndMessage; 338748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 338848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 338948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 339048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 339148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUseProgram(m_program_b); 339248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDispatchCompute(1, 1, 1); 339348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT); 339448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 339548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* validate */ 339648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 339748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos int data; 339848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, sizeof(int), &data); 339948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (data != 2) 340048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 3401910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() 3402910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << tcu::TestLog::Message << "Data is " << data << " should be 2." << tcu::TestLog::EndMessage; 340348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 340448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 340548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 340648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 340748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUseProgram(0); 340848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUseProgramStages(m_pipeline, GL_COMPUTE_SHADER_BIT, m_program_a); 340948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDispatchCompute(1, 1, 1); 341048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT); 341148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 341248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* validate */ 341348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 341448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos int data; 341548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, sizeof(int), &data); 341648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (data != 1) 341748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 3418910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() 3419910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << tcu::TestLog::Message << "Data is " << data << " should be 1." << tcu::TestLog::EndMessage; 342048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 342148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 342248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 342348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 342448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 342548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 342648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Cleanup() 342748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 342848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteProgram(m_program_a); 342948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteProgram(m_program_b); 343048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteProgramPipelines(1, &m_pipeline); 343148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteBuffers(1, &m_storage_buffer); 343248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 343348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 343448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}; 343548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 343648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosclass BasicAtomicCase1 : public ComputeShaderBase 343748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 343848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Title() 343948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 344048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "Atomic functions"; 344148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 344248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Purpose() 344348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 344448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "1. Verify that atomicAdd function works as expected with int and uint parameters." NL 344548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "2. Verify that shared memory can be used with atomic functions." NL 344648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "3. Verify that groupMemoryBarrier() and barrier() built-in functions work as expected."; 344748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 344848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Method() 344948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 345048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "1. Use shared memory as a 'counter' with-in one CS work group." NL 345148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "2. Each shader invocation increments/decrements 'counter' value using atomicAdd function." NL 345248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "3. Values returned by atomicAdd function are written to SSBO." NL 345348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "4. Verify SSBO content (values from 0 to 7 should be written)."; 345448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 345548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string PassCriteria() 345648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 345748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "Everything works as expected."; 345848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 345948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 346048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_program; 346148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_storage_buffer; 346248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 346348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Setup() 346448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 346548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_program = 0; 346648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_storage_buffer = 0; 346748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 346848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 346948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Run() 347048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 347148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* const glsl_cs = 347248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos NL "layout(local_size_x = 8) in;" NL "layout(std430, binding = 0) buffer Output {" NL 347348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " uint g_add_output[8];" NL " int g_sub_output[8];" NL "};" NL "shared uint g_add_value;" NL 347448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "shared int g_sub_value;" NL "void main() {" NL " if (gl_LocalInvocationIndex == 0) {" NL 347548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " g_add_value = 0u;" NL " g_sub_value = 7;" NL " }" NL 347648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " g_add_output[gl_LocalInvocationIndex] = 0u;" NL " g_sub_output[gl_LocalInvocationIndex] = 0;" NL 347748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " groupMemoryBarrier();" NL " barrier();" NL 347848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " g_add_output[gl_LocalInvocationIndex] = atomicAdd(g_add_value, 1u);" NL 347948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " g_sub_output[gl_LocalInvocationIndex] = atomicAdd(g_sub_value, -1);" NL "}"; 348048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_program = CreateComputeProgram(glsl_cs); 348148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glLinkProgram(m_program); 348248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!CheckProgram(m_program)) 348348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 348448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 348548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGenBuffers(1, &m_storage_buffer); 348648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_storage_buffer); 348748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBufferData(GL_SHADER_STORAGE_BUFFER, 16 * sizeof(int), NULL, GL_STATIC_DRAW); 348848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 348948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUseProgram(m_program); 349048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDispatchCompute(1, 1, 1); 349148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT); 349248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 349348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::vector<int> data(8); 349448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, sizeof(int) * 8, &data[0]); 349548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::sort(data.begin(), data.end()); 349648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (int i = 0; i < 8; ++i) 349748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 349848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (data[i] != i) 349948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 3500910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() << tcu::TestLog::Message << "Data at index " << i << " is " 3501910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << data[i] << " should be " << i << "." << tcu::TestLog::EndMessage; 350248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 350348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 350448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 350548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 350648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetBufferSubData(GL_SHADER_STORAGE_BUFFER, sizeof(int) * 8, sizeof(int) * 8, &data[0]); 350748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::sort(data.begin(), data.end()); 350848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (int i = 0; i < 8; ++i) 350948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 351048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (data[i] != i) 351148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 3512910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() << tcu::TestLog::Message << "Data at index " << i << " is " 3513910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << data[i] << " should be " << i << "." << tcu::TestLog::EndMessage; 351448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 351548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 351648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 351748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 351848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 351948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 352048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Cleanup() 352148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 352248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUseProgram(0); 352348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteProgram(m_program); 352448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteBuffers(1, &m_storage_buffer); 352548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 352648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 352748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}; 352848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 352948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosclass BasicAtomicCase2 : public ComputeShaderBase 353048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 353148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Title() 353248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 353348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "Atomic functions - buffer variables"; 353448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 353548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Purpose() 353648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 353748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "1. Verify that all atomic functions (atomicExchange, atomicMin, atomicMax," NL 353848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " atomicAnd, atomicOr, atomicXor and atomicCompSwap) works as expected with buffer variables." NL 353948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "2. Verify that atomic functions work with parameters being constants and" NL 354048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " with parameters being uniforms." NL 354148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "3. Verify that barrier() built-in function can be used in a control flow."; 354248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 354348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Method() 354448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 354548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "1. Create CS that uses all atomic functions. Values returned by the atomic functions are written to " 354648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "SSBO." NL "2. Dispatch CS with DispatchCompute and DispatchComputeIndirect commands." NL 354748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "3. Verify SSBO content." NL 354848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "4. Repeat for different number of work groups and different work group sizes."; 354948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 355048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string PassCriteria() 355148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 355248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "Everything works as expected."; 355348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 355448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 355548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_program; 355648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_storage_buffer[2]; 355748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_dispatch_buffer; 355848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 355948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::string GenSource(const uvec3& local_size, const uvec3& num_groups) 356048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 356148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const uvec3 global_size = local_size * num_groups; 356248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::stringstream ss; 356348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos ss << NL "layout(local_size_x = " << local_size.x() << ", local_size_y = " << local_size.y() 356448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << ", local_size_z = " << local_size.z() << ") in;" NL "const uvec3 kGlobalSize = uvec3(" << global_size.x() 356548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << ", " << global_size.y() << ", " << global_size.z() 356648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << ");" NL "layout(std430, binding = 0) buffer OutputU {" NL " uint g_uint_out[" 356748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << global_size.x() * global_size.y() * global_size.z() 356848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << "];" NL "};" NL "layout(std430, binding = 1) buffer OutputI {" NL " int data[" 356948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << global_size.x() * global_size.y() * global_size.z() 357048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << "];" NL "} g_int_out;" NL 357148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "uniform uint g_uint_value[8] = uint[8](3u, 1u, 2u, 0x1u, 0x3u, 0x1u, 0x2u, 0x7u);" NL "void main() {" NL 357248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " const uint global_index = gl_GlobalInvocationID.x +" NL 357348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " gl_GlobalInvocationID.y * kGlobalSize.x +" NL 357448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " gl_GlobalInvocationID.z * kGlobalSize.x * kGlobalSize.y;" NL 357548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " atomicExchange(g_uint_out[global_index], g_uint_value[0]);" NL 357648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " atomicMin(g_uint_out[global_index], g_uint_value[1]);" NL 357748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " atomicMax(g_uint_out[global_index], g_uint_value[2]);" NL 357848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " atomicAnd(g_uint_out[global_index], g_uint_value[3]);" NL 357948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " atomicOr(g_uint_out[global_index], g_uint_value[4]);" NL " if (g_uint_value[0] > 0u) {" NL 358048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " barrier();" // not needed here, just check if compiler accepts it in a control flow 358148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos NL " atomicXor(g_uint_out[global_index], g_uint_value[5]);" NL " }" NL 358248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " atomicCompSwap(g_uint_out[global_index], g_uint_value[6], g_uint_value[7]);" NL NL 358348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " atomicExchange(g_int_out.data[global_index], 3);" NL " atomicMin(g_int_out.data[global_index], 1);" NL 358448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " atomicMax(g_int_out.data[global_index], 2);" NL " atomicAnd(g_int_out.data[global_index], 0x1);" NL 358548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " atomicOr(g_int_out.data[global_index], 0x3);" NL " atomicXor(g_int_out.data[global_index], 0x1);" NL 358648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " atomicCompSwap(g_int_out.data[global_index], 0x2, 0x7);" NL "}"; 358748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ss.str(); 358848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 358948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos bool RunIteration(const uvec3& local_size, const uvec3& num_groups, bool dispatch_indirect) 359048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 359148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_program != 0) 359248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteProgram(m_program); 359348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_program = CreateComputeProgram(GenSource(local_size, num_groups)); 359448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glLinkProgram(m_program); 359548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!CheckProgram(m_program)) 359648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return false; 359748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 359848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLuint kBufferSize = 359948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos local_size.x() * num_groups.x() * local_size.y() * num_groups.y() * local_size.z() * num_groups.z(); 360048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 360148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_storage_buffer[0] == 0) 360248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGenBuffers(2, m_storage_buffer); 360348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_storage_buffer[0]); 360448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(GLuint) * kBufferSize, NULL, GL_DYNAMIC_DRAW); 360548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_storage_buffer[1]); 360648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(GLint) * kBufferSize, NULL, GL_DYNAMIC_DRAW); 360748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 360848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUseProgram(m_program); 360948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (dispatch_indirect) 361048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 361148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_dispatch_buffer == 0) 361248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGenBuffers(1, &m_dispatch_buffer); 361348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBuffer(GL_DISPATCH_INDIRECT_BUFFER, m_dispatch_buffer); 361448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBufferData(GL_DISPATCH_INDIRECT_BUFFER, sizeof(num_groups), &num_groups[0], GL_STATIC_DRAW); 361548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDispatchComputeIndirect(0); 361648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 361748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else 361848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 361948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDispatchCompute(num_groups.x(), num_groups.y(), num_groups.z()); 362048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 362148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT); 362248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 362348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::vector<GLuint> udata(kBufferSize); 362448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer[0]); 362548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, sizeof(GLuint) * kBufferSize, &udata[0]); 362648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLuint i = 0; i < kBufferSize; ++i) 362748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 362848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (udata[i] != 7) 362948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 3630910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() << tcu::TestLog::Message << "uData at index " << i << " is " 3631910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << udata[i] << " should be 7." << tcu::TestLog::EndMessage; 363248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return false; 363348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 363448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 363548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 363648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::vector<GLint> idata(kBufferSize); 363748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer[1]); 363848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, sizeof(GLint) * kBufferSize, &idata[0]); 363948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLint i = 0; i < static_cast<GLint>(kBufferSize); ++i) 364048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 364148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (idata[i] != 7) 364248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 3643910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() << tcu::TestLog::Message << "Data at index " << i << " is " 3644910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << idata[i] << " should be 7." << tcu::TestLog::EndMessage; 364548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return false; 364648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 364748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 364848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 364948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return true; 365048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 365148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Setup() 365248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 365348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_program = 0; 365448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_storage_buffer[0] = m_storage_buffer[1] = 0; 365548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_dispatch_buffer = 0; 365648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 365748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 365848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Run() 365948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 366048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!RunIteration(uvec3(64, 1, 1), uvec3(8, 1, 1), false)) 366148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 366248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!RunIteration(uvec3(1, 1, 64), uvec3(1, 5, 2), true)) 366348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 366448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!RunIteration(uvec3(1, 1, 4), uvec3(2, 2, 2), false)) 366548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 366648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!RunIteration(uvec3(3, 2, 1), uvec3(1, 2, 3), true)) 366748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 366848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!RunIteration(uvec3(2, 4, 2), uvec3(2, 4, 1), false)) 366948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 367048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!RunIteration(uvec3(2, 4, 7), uvec3(2, 1, 4), true)) 367148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 367248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 367348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 367448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Cleanup() 367548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 367648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUseProgram(0); 367748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteProgram(m_program); 367848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteBuffers(2, m_storage_buffer); 367948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteBuffers(1, &m_dispatch_buffer); 368048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 368148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 368248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}; 368348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 368448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosclass BasicAtomicCase3 : public ComputeShaderBase 368548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 368648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Title() 368748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 368848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "Atomic functions - shared variables"; 368948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 369048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Purpose() 369148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 369248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "1. Verify that all atomic functions (atomicExchange, atomicMin, atomicMax," NL 369348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " atomicAnd, atomicOr, atomicXor and atomicCompSwap) works as expected with shared variables." NL 369448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "2. Verify that atomic functions work with parameters being constants and" NL 369548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " with parameters being uniforms." NL 369648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "3. Verify that atomic functions can be used in a control flow."; 369748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 369848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Method() 369948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 370048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "1. Create CS that uses all atomic functions. Values returned by the atomic functions are written to " 370148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "SSBO." NL "2. Dispatch CS with DispatchCompute and DispatchComputeIndirect commands." NL 370248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "3. Verify SSBO content." NL 370348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "4. Repeat for different number of work groups and different work group sizes."; 370448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 370548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string PassCriteria() 370648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 370748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "Everything works as expected."; 370848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 370948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 371048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_program; 371148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_storage_buffer; 371248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_dispatch_buffer; 371348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 371448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::string GenSource(const uvec3& local_size) 371548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 371648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::stringstream ss; 371748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos ss << NL "layout(local_size_x = " << local_size.x() << ", local_size_y = " << local_size.y() 371848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << ", local_size_z = " << local_size.z() 371948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << ") in;" NL "layout(std430, binding = 0) buffer Output {" NL " uint g_uint_out[" 372048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << local_size.x() * local_size.y() * local_size.z() << "];" NL " int g_int_out[" 372148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << local_size.x() * local_size.y() * local_size.z() << "];" NL "};" NL "shared uint g_shared_uint[" 372248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << local_size.x() * local_size.y() * local_size.z() << "];" NL "shared int g_shared_int[" 372348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << local_size.x() * local_size.y() * local_size.z() 372448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << "];" NL "uniform uint g_uint_value[8] = uint[8](3u, 1u, 2u, 0x1u, 0x3u, 0x1u, 0x2u, 0x7u);" NL 372548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void main() {" NL " atomicExchange(g_shared_uint[gl_LocalInvocationIndex], g_uint_value[0]);" NL 372648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " atomicMin(g_shared_uint[gl_LocalInvocationIndex], g_uint_value[1]);" NL 372748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " atomicMax(g_shared_uint[gl_LocalInvocationIndex], g_uint_value[2]);" NL 372848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " atomicAnd(g_shared_uint[gl_LocalInvocationIndex], g_uint_value[3]);" NL 372948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " atomicOr(g_shared_uint[gl_LocalInvocationIndex], g_uint_value[4]);" NL 373048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " atomicXor(g_shared_uint[gl_LocalInvocationIndex], g_uint_value[5]);" NL 373148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " atomicCompSwap(g_shared_uint[gl_LocalInvocationIndex], g_uint_value[6], g_uint_value[7]);" NL NL 373248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " atomicExchange(g_shared_int[gl_LocalInvocationIndex], 3);" NL 373348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " atomicMin(g_shared_int[gl_LocalInvocationIndex], 1);" NL 373448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " atomicMax(g_shared_int[gl_LocalInvocationIndex], 2);" NL 373548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " atomicAnd(g_shared_int[gl_LocalInvocationIndex], 0x1);" NL " if (g_uint_value[1] > 0u) {" NL 373648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " atomicOr(g_shared_int[gl_LocalInvocationIndex], 0x3);" NL 373748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " atomicXor(g_shared_int[gl_LocalInvocationIndex], 0x1);" NL 373848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " atomicCompSwap(g_shared_int[gl_LocalInvocationIndex], 0x2, 0x7);" NL " }" NL NL 373948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " g_uint_out[gl_LocalInvocationIndex] = g_shared_uint[gl_LocalInvocationIndex];" NL 374048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " g_int_out[gl_LocalInvocationIndex] = g_shared_int[gl_LocalInvocationIndex];" NL "}"; 374148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ss.str(); 374248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 374348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos bool RunIteration(const uvec3& local_size, bool dispatch_indirect) 374448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 374548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_program != 0) 374648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteProgram(m_program); 374748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_program = CreateComputeProgram(GenSource(local_size)); 374848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glLinkProgram(m_program); 374948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!CheckProgram(m_program)) 375048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return false; 375148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 375248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLuint kBufferSize = local_size.x() * local_size.y() * local_size.z(); 375348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 375448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_storage_buffer == 0) 375548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGenBuffers(1, &m_storage_buffer); 375648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_storage_buffer); 375748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(GLuint) * kBufferSize * 2, NULL, GL_DYNAMIC_DRAW); 375848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 375948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUseProgram(m_program); 376048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (dispatch_indirect) 376148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 376248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLuint num_groups[3] = { 1, 1, 1 }; 376348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_dispatch_buffer == 0) 376448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGenBuffers(1, &m_dispatch_buffer); 376548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBuffer(GL_DISPATCH_INDIRECT_BUFFER, m_dispatch_buffer); 376648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBufferData(GL_DISPATCH_INDIRECT_BUFFER, sizeof(num_groups), &num_groups[0], GL_STATIC_DRAW); 376748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDispatchComputeIndirect(0); 376848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 376948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else 377048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 377148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDispatchCompute(1, 1, 1); 377248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 377348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT); 377448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 377548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::vector<GLuint> udata(kBufferSize); 377648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, sizeof(GLuint) * kBufferSize, &udata[0]); 377748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLuint i = 0; i < kBufferSize; ++i) 377848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 377948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (udata[i] != 7) 378048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 3781910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() << tcu::TestLog::Message << "uData at index " << i << " is " 3782910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << udata[i] << " should be 7." << tcu::TestLog::EndMessage; 378348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return false; 378448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 378548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 378648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 378748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::vector<GLint> idata(kBufferSize); 378848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetBufferSubData(GL_SHADER_STORAGE_BUFFER, sizeof(GLuint) * kBufferSize, sizeof(GLint) * kBufferSize, 378948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos &idata[0]); 379048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLint i = 0; i < static_cast<GLint>(kBufferSize); ++i) 379148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 379248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (idata[i] != 7) 379348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 3794910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() << tcu::TestLog::Message << "iData at index " << i << " is " 3795910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << idata[i] << " should be 7." << tcu::TestLog::EndMessage; 379648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return false; 379748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 379848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 379948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 380048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return true; 380148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 380248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Setup() 380348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 380448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_program = 0; 380548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_storage_buffer = 0; 380648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_dispatch_buffer = 0; 380748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 380848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 380948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Run() 381048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 381148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!RunIteration(uvec3(64, 1, 1), false)) 381248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 381348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!RunIteration(uvec3(1, 1, 64), true)) 381448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 381548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!RunIteration(uvec3(1, 1, 4), false)) 381648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 381748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!RunIteration(uvec3(3, 2, 1), true)) 381848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 381948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!RunIteration(uvec3(2, 4, 2), false)) 382048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 382148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!RunIteration(uvec3(2, 4, 7), true)) 382248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 382348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 382448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 382548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Cleanup() 382648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 382748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUseProgram(0); 382848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteProgram(m_program); 382948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteBuffers(1, &m_storage_buffer); 383048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteBuffers(1, &m_dispatch_buffer); 383148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 383248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 383348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}; 383448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 383548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosclass AdvancedCopyImage : public ComputeShaderBase 383648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 383748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Title() 383848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 383948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "Copy Image"; 384048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 384148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Purpose() 384248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 384348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "Verify that copying two textures using CS works as expected."; 384448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 384548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Method() 384648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 384748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "Use shader image load and store operations to copy two textures in the CS."; 384848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 384948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string PassCriteria() 385048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 385148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "Everything works as expected."; 385248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 385348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 385448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_program; 385548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_texture[2]; 385648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 385748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Setup() 385848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 385948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_program = 0; 386048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos memset(m_texture, 0, sizeof(m_texture)); 386148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 386248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 386348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 386448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Run() 386548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 386648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* const glsl_cs = NL "#define TILE_WIDTH 16" NL "#define TILE_HEIGHT 16" NL 386748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "const ivec2 kTileSize = ivec2(TILE_WIDTH, TILE_HEIGHT);" NL NL 386848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "layout(binding = 0, rgba8) uniform image2D g_input_image;" NL 386948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "layout(binding = 1, rgba8) uniform image2D g_output_image;" NL NL 387048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "layout(local_size_x=TILE_WIDTH, local_size_y=TILE_HEIGHT) in;" NL NL 387148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void main() {" NL " const ivec2 tile_xy = ivec2(gl_WorkGroupID);" NL 387248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " const ivec2 thread_xy = ivec2(gl_LocalInvocationID);" NL 387348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " const ivec2 pixel_xy = tile_xy * kTileSize + thread_xy;" NL NL 387448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " vec4 pixel = imageLoad(g_input_image, pixel_xy);" NL 387548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " imageStore(g_output_image, pixel_xy, pixel);" NL "}"; 387648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_program = CreateComputeProgram(glsl_cs); 387748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glLinkProgram(m_program); 387848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!CheckProgram(m_program)) 387948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 388048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 388148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::vector<GLubyte> in_image(64 * 64 * 4, 0x0f); 388248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::vector<GLubyte> out_image(64 * 64 * 4, 0x00); 388348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 388448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGenTextures(2, m_texture); 388548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindTexture(GL_TEXTURE_2D, m_texture[0]); 388648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 388748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 64, 64, 0, GL_RGBA, GL_UNSIGNED_BYTE, &in_image[0]); 388848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 388948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindTexture(GL_TEXTURE_2D, m_texture[1]); 389048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 389148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 64, 64, 0, GL_RGBA, GL_UNSIGNED_BYTE, &out_image[0]); 389248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 389348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUseProgram(m_program); 389448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindImageTexture(0, m_texture[0], 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA8); 389548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindImageTexture(1, m_texture[1], 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA8); 389648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDispatchCompute(5, 4, 389748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1); // 5 is on purpose, to ensure that out of bounds image load and stores have no effect 389848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glMemoryBarrier(GL_TEXTURE_UPDATE_BARRIER_BIT); 389948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 390048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::vector<GLubyte> data(64 * 64 * 4); 390148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, &data[0]); 390248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (std::size_t i = 0; i < data.size(); ++i) 390348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 390448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (getWindowWidth() > 100 && data[i] != 0x0f) 390548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 3906910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() 3907910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << tcu::TestLog::Message << "Data at index " << i << " is " << data[i] << " should be " << 0x0f 3908910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << "." << tcu::TestLog::EndMessage; 390948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 391048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 391148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 391248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 391348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 391448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 391548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Cleanup() 391648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 391748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUseProgram(0); 391848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteProgram(m_program); 391948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteTextures(2, m_texture); 392048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 392148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 392248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}; 392348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 392448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosclass AdvancedPipelinePreVS : public ComputeShaderBase 392548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 392648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Title() 392748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 392848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "CS as an additional pipeline stage - Before VS (1)"; 392948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 393048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Purpose() 393148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 393248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "Verify that CS which runs just before VS and modifies VBO content works as expected."; 393348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 393448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Method() 393548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 393648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "1. Prepare VBO and VAO for a drawing operation." NL "2. Run CS to modify existing VBO content." NL 393748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "3. Issue MemoryBarrier(GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT) command." NL 393848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "4. Issue draw call command." NL "5. Verify that the framebuffer content is as expected."; 393948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 394048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string PassCriteria() 394148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 394248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "Everything works as expected."; 394348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 394448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 394548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_program[2]; 394648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_vertex_buffer; 394748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_vertex_array; 394848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 394948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Setup() 395048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 395148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos memset(m_program, 0, sizeof(m_program)); 395248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_vertex_buffer = 0; 395348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_vertex_array = 0; 395448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 395548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 395648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Run() 395748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 395848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* const glsl_cs = 395948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos NL "layout(local_size_x = 4) in;" NL "struct Vertex {" NL " vec4 position;" NL " vec4 color;" NL "};" NL 396048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "layout(binding = 0, std430) buffer VertexBuffer {" NL " Vertex g_vertex[];" NL "};" NL 396148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "uniform float g_scale = 0.8;" NL "void main() {" NL 396248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " g_vertex[gl_GlobalInvocationID.x].position.xyz *= g_scale;" NL 396348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " g_vertex[gl_GlobalInvocationID.x].color *= vec4(0, 1, 0, 1);" NL "}"; 396448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_program[0] = CreateComputeProgram(glsl_cs); 396548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glLinkProgram(m_program[0]); 396648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!CheckProgram(m_program[0])) 396748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 396848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 396948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* const glsl_vs = 397048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos NL "layout(location = 0) in vec4 g_position;" NL "layout(location = 1) in vec4 g_color;" NL 397148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "out StageData {" NL " vec4 color;" NL "} g_vs_out;" NL "void main() {" NL 397248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " gl_Position = g_position;" NL " g_vs_out.color = g_color;" NL "}"; 397348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 397448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* const glsl_fs = 397548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos NL "in StageData {" NL " vec4 color;" NL "} g_fs_in;" NL "layout(location = 0) out vec4 g_color;" NL 397648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void main() {" NL " g_color = g_fs_in.color;" NL "}"; 397748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_program[1] = CreateProgram(glsl_vs, glsl_fs); 397848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glLinkProgram(m_program[1]); 397948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!CheckProgram(m_program[1])) 398048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 398148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 398248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* vertex buffer */ 398348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 398448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const float data[] = { -1, -1, 0, 1, 1, 1, 1, 1, 1, -1, 0, 1, 1, 1, 1, 1, 398548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos -1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1 }; 398648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGenBuffers(1, &m_vertex_buffer); 398748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBuffer(GL_ARRAY_BUFFER, m_vertex_buffer); 398848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBufferData(GL_ARRAY_BUFFER, sizeof(data), data, GL_STATIC_DRAW); 398948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBuffer(GL_ARRAY_BUFFER, 0); 399048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 399148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 399248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGenVertexArrays(1, &m_vertex_array); 399348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindVertexArray(m_vertex_array); 399448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBuffer(GL_ARRAY_BUFFER, m_vertex_buffer); 399548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 2 * sizeof(vec4), 0); 399648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 2 * sizeof(vec4), reinterpret_cast<void*>(sizeof(vec4))); 399748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBuffer(GL_ARRAY_BUFFER, 0); 399848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glEnableVertexAttribArray(0); 399948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glEnableVertexAttribArray(1); 400048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindVertexArray(0); 400148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 400248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_vertex_buffer); 400348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUseProgram(m_program[0]); 400448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDispatchCompute(1, 1, 1); 400548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 400648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glClear(GL_COLOR_BUFFER_BIT); 400748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUseProgram(m_program[1]); 400848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindVertexArray(m_vertex_array); 400948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glMemoryBarrier(GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT); 401048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, 1); 401148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 401248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (getWindowWidth() < 500 && 401348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos !ValidateReadBufferCenteredQuad(getWindowWidth(), getWindowHeight(), vec3(0, 1, 0))) 401448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 401548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 401648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 401748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 401848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 401948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Cleanup() 402048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 402148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUseProgram(0); 402248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (int i = 0; i < 2; ++i) 402348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteProgram(m_program[i]); 402448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteBuffers(1, &m_vertex_buffer); 402548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteVertexArrays(1, &m_vertex_array); 402648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 402748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 402848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}; 402948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 403048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosclass AdvancedPipelineGenDrawCommands : public ComputeShaderBase 403148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 403248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Title() 403348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 403448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "CS as an additional pipeline stage - Before VS (2)"; 403548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 403648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Purpose() 403748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 403848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "Verify that a complex scenario where CS is used to generate drawing commands" NL 403948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "and write them to a draw indirect buffer works as expected. This is a practial usage of CS." NL 404048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "CS is used for culling objects which are outside of the viewing frustum."; 404148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 404248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Method() 404348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 404448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "1. Run CS which will generate four sets of draw call parameters and write them to the draw indirect " 404548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "buffer." NL "2. One set of draw call parameters will be: 0, 0, 0, 0" NL 404648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " (which means that an object is outside of the viewing frustum and should not be drawn)." NL 404748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "3. Issue MemoryBarrier(GL_COMMAND_BARRIER_BIT) command." NL 404848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "4. Issue four draw indirect commands." NL "5. Verify that the framebuffer content is as expected."; 404948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 405048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string PassCriteria() 405148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 405248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "Everything works as expected."; 405348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 405448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 405548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_program[2]; 405648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_vertex_buffer; 405748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_index_buffer; 405848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_vertex_array; 405948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_draw_buffer; 406048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_object_buffer; 406148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 406248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Setup() 406348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 406448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos memset(m_program, 0, sizeof(m_program)); 406548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_vertex_buffer = 0; 406648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_index_buffer = 0; 406748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_vertex_array = 0; 406848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_draw_buffer = 0; 406948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_object_buffer = 0; 407048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 407148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 407248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Run() 407348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 407448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLint res; 407548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetIntegerv(GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS, &res); 407648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (res <= 0) 407748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 407848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos OutputNotSupported("GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS <= 0"); 407948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 408048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 408148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 408248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* const glsl_cs = 408348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos NL "layout(local_size_x = 4) in;" NL "struct DrawCommand {" NL " uint count;" NL 408448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " uint instance_count;" NL " uint first_index;" NL " int base_vertex;" NL " uint base_instance;" NL 408548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "};" NL "layout(std430) buffer;" NL "layout(binding = 0) readonly buffer ObjectBuffer {" NL 408648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " mat4 transform[4];" NL " uint count[4];" NL " uint first_index[4];" NL "} g_objects;" NL 408748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "layout(binding = 1) writeonly buffer DrawCommandBuffer {" NL " DrawCommand g_command[4];" NL "};" NL 408848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "bool IsObjectVisible(uint id) {" NL 408948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " if (g_objects.transform[id][3].x < -1.0 || g_objects.transform[id][3].x > 1.0) return false;" NL 409048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " if (g_objects.transform[id][3][1] < -1.0 || g_objects.transform[id][3][1] > 1.0) return false;" NL 409148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " if (g_objects.transform[id][3][2] < -1.0 || g_objects.transform[id][3].z > 1.0) return false;" NL 409248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " return true;" NL "}" NL "void main() {" NL " uint id = gl_GlobalInvocationID.x;" NL 409348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " g_command[id].count = 0;" NL " g_command[id].instance_count = 0;" NL 409448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " g_command[id].first_index = 0;" NL " g_command[id].base_vertex = 0;" NL 409548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " g_command[id].base_instance = 0;" NL " if (IsObjectVisible(id)) {" NL 409648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " g_command[id].count = g_objects.count[id];" NL " g_command[id].instance_count = 1;" NL 409748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " g_command[id].first_index = g_objects.first_index[id];" NL " }" NL "}"; 409848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_program[0] = CreateComputeProgram(glsl_cs); 409948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glLinkProgram(m_program[0]); 410048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!CheckProgram(m_program[0])) 410148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 410248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 410348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* const glsl_vs = 410448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos NL "layout(location = 0) in vec4 g_position;" NL "layout(location = 1) in vec3 g_color;" NL 410548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "out StageData {" NL " vec3 color;" NL "} g_vs_out;" NL 410648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "layout(binding = 0, std430) buffer ObjectBuffer {" NL " mat4 transform[4];" NL " uint count[4];" NL 410748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " uint first_index[4];" NL "} g_objects;" NL "uniform int g_object_id;" NL "void main() {" NL 410848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " gl_Position = g_objects.transform[g_object_id] * g_position;" NL " g_vs_out.color = g_color;" NL "}"; 410948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 411048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* const glsl_fs = 411148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos NL "in StageData {" NL " vec3 color;" NL "} g_fs_in;" NL "layout(location = 0) out vec4 g_color;" NL 411248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void main() {" NL " g_color = vec4(g_fs_in.color, 1);" NL "}"; 411348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_program[1] = CreateProgram(glsl_vs, glsl_fs); 411448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glLinkProgram(m_program[1]); 411548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!CheckProgram(m_program[1])) 411648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 411748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glViewport(0, 0, 100, 100); 411848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 411948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* object buffer */ 412048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 412148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos struct 412248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 412348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos mat4 transform[4]; 412448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint count[4]; 412548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint first_index[4]; 412648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } data = { 412748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { tcu::translationMatrix(vec3(-1.5f, -0.5f, 0.0f)), tcu::translationMatrix(vec3(0.5f, -0.5f, 0.0f)), 412848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos tcu::translationMatrix(vec3(-0.5f, 0.5f, 0.0f)), tcu::translationMatrix(vec3(0.5f, 0.5f, 0.0f)) }, 412948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 4, 4, 4, 4 }, 413048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 0, 4, 8, 12 } 413148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos }; 413248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGenBuffers(1, &m_object_buffer); 413348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_object_buffer); 413448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), &data, GL_STATIC_DRAW); 413548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 413648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* vertex buffer */ 413748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 413848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const vec3 data[] = { vec3(-0.4f, -0.4f, 0.0f), vec3(1, 0, 0), vec3(0.4f, -0.4f, 0.0f), vec3(1, 0, 0), 413948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos vec3(-0.4f, 0.4f, 0.0f), vec3(1, 0, 0), vec3(0.4f, 0.4f, 0.0f), vec3(1, 0, 0), 414048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos vec3(-0.4f, -0.4f, 0.0f), vec3(0, 1, 0), vec3(0.4f, -0.4f, 0.0f), vec3(0, 1, 0), 414148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos vec3(-0.4f, 0.4f, 0.0f), vec3(0, 1, 0), vec3(0.4f, 0.4f, 0.0f), vec3(0, 1, 0), 414248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos vec3(-0.4f, -0.4f, 0.0f), vec3(0, 0, 1), vec3(0.4f, -0.4f, 0.0f), vec3(0, 0, 1), 414348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos vec3(-0.4f, 0.4f, 0.0f), vec3(0, 0, 1), vec3(0.4f, 0.4f, 0.0f), vec3(0, 0, 1), 414448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos vec3(-0.4f, -0.4f, 0.0f), vec3(1, 1, 0), vec3(0.4f, -0.4f, 0.0f), vec3(1, 1, 0), 414548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos vec3(-0.4f, 0.4f, 0.0f), vec3(1, 1, 0), vec3(0.4f, 0.4f, 0.0f), vec3(1, 1, 0) }; 414648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGenBuffers(1, &m_vertex_buffer); 414748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBuffer(GL_ARRAY_BUFFER, m_vertex_buffer); 414848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBufferData(GL_ARRAY_BUFFER, sizeof(data), data, GL_STATIC_DRAW); 414948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBuffer(GL_ARRAY_BUFFER, 0); 415048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 415148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* index buffer */ 415248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 415348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLushort data[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }; 415448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGenBuffers(1, &m_index_buffer); 415548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_index_buffer); 415648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(data), data, GL_DYNAMIC_DRAW); 415748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); 415848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 415948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGenBuffers(1, &m_draw_buffer); 416048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBuffer(GL_DRAW_INDIRECT_BUFFER, m_draw_buffer); 416148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBufferData(GL_DRAW_INDIRECT_BUFFER, 4 * sizeof(GLuint) * 5, NULL, GL_DYNAMIC_DRAW); 416248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBuffer(GL_DRAW_INDIRECT_BUFFER, 0); 416348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 416448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGenVertexArrays(1, &m_vertex_array); 416548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindVertexArray(m_vertex_array); 416648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBuffer(GL_ARRAY_BUFFER, m_vertex_buffer); 416748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 2 * sizeof(vec3), 0); 416848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 2 * sizeof(vec3), reinterpret_cast<void*>(sizeof(vec3))); 416948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBuffer(GL_ARRAY_BUFFER, 0); 417048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glEnableVertexAttribArray(0); 417148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glEnableVertexAttribArray(1); 417248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_index_buffer); 417348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindVertexArray(0); 417448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 417548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_draw_buffer); 417648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUseProgram(m_program[0]); 417748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDispatchCompute(1, 1, 1); 417848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 417948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glClear(GL_COLOR_BUFFER_BIT); 418048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUseProgram(m_program[1]); 418148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindVertexArray(m_vertex_array); 418248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBuffer(GL_DRAW_INDIRECT_BUFFER, m_draw_buffer); 418348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glMemoryBarrier(GL_COMMAND_BARRIER_BIT); 418448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* draw (CPU draw calls dispatch, could be done by the GPU with ARB_multi_draw_indirect) */ 418548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 418648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLsizeiptr offset = 0; 418748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (int i = 0; i < 4; ++i) 418848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 418948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUniform1i(glGetUniformLocation(m_program[1], "g_object_id"), i); 419048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDrawElementsIndirect(GL_TRIANGLE_STRIP, GL_UNSIGNED_SHORT, reinterpret_cast<void*>(offset)); 419148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos offset += 5 * sizeof(GLuint); 419248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 419348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 419448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (getWindowWidth() >= 100 && getWindowHeight() >= 100 && 419548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos !ValidateWindow4Quads(vec3(0), vec3(0, 1, 0), vec3(1, 1, 0), vec3(0, 0, 1))) 419648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 419748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 419848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 419948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 420048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 420148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Cleanup() 420248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 420348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUseProgram(0); 420448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (int i = 0; i < 2; ++i) 420548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteProgram(m_program[i]); 420648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteBuffers(1, &m_vertex_buffer); 420748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteBuffers(1, &m_index_buffer); 420848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteVertexArrays(1, &m_vertex_array); 420948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteBuffers(1, &m_draw_buffer); 421048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteBuffers(1, &m_object_buffer); 421148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glViewport(0, 0, getWindowWidth(), getWindowHeight()); 421248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 421348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 421448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}; 421548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 421648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosclass AdvancedPipelineComputeChain : public ComputeShaderBase 421748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 421848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Title() 421948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 422048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "Compute Chain"; 422148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 422248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Purpose() 422348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 422448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "1. Verify that dispatching several compute kernels that work in a sequence" NL 422548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " with a common set of resources works as expected." NL 422648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "2. Verify that indexing nested structures with built-in variables work as expected." NL 422748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "3. Verify that two kernels can write to the same resource without MemoryBarrier" NL 422848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " command if target regions of memory do not overlap."; 422948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 423048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Method() 423148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 423248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "1. Create a set of GPU resources (buffers, images, atomic counters)." NL 423348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "2. Dispatch Kernel0 that write to these resources." NL "3. Issue MemoryBarrier command." NL 423448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "4. Dispatch Kernel1 that read/write from/to these resources." NL "5. Issue MemoryBarrier command." NL 423548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "6. Dispatch Kernel2 that read/write from/to these resources." NL 423648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "7. Verify that content of all resources is as expected."; 423748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 423848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string PassCriteria() 423948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 424048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "Everything works as expected."; 424148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 424248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 424348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_program[3]; 424448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_storage_buffer[4]; 424548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_counter_buffer; 424648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_texture; 424748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_fbo; 424848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 424948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::string Common() 425048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 425148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "struct S0 {" NL " int m0[8];" NL "};" NL "struct S1 {" NL " S0 m0[8];" NL "};" NL 425248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "layout(binding = 0, std430) buffer Buffer0 {" NL " int m0[5];" NL " S1 m1[8];" NL "} g_buffer0;" NL 425348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "layout(binding = 1, std430) buffer Buffer1 {" NL " uint data[8];" NL "} g_buffer1;" NL 425448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "layout(binding = 2, std430) buffer Buffer2 {" NL " int data[256];" NL "} g_buffer2;" NL 425548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "layout(binding = 3, std430) buffer Buffer3 {" NL " int data[256];" NL "} g_buffer3;" NL 425648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "layout(binding = 4, std430) buffer Buffer4 {" NL " mat4 data0;" NL " mat4 data1;" NL 425748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "} g_buffer4;" NL "layout(binding = 0, rgba32f) uniform image2D g_image0;" NL 425848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "layout(binding = 1, offset = 8) uniform atomic_uint g_counter[2];"; 425948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 426048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::string GenGLSL(int p) 426148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 426248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::stringstream ss; 426348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos ss << Common(); 426448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (p == 0) 426548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 426648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos ss << NL "layout(local_size_x = 4, local_size_y = 4, local_size_z = 4) in;" NL 426748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void UpdateBuffer0(uvec3 id, int add_val) {" NL " if (id.x < 8 && id.y < 8 && id.z < 8) {" NL 426848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " g_buffer0.m1[id.z].m0[id.y].m0[id.x] += add_val;" NL " }" NL "}" NL 426948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "uniform int g_add_value = 1;" NL "uniform uint g_counter_y = 1;" NL 427048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "uniform vec4 g_image_value = vec4(0.125, 0.25, 0.375, 0.5);" NL "void main() {" NL 427148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " uvec3 id = gl_GlobalInvocationID;" NL " UpdateBuffer0(id, 1);" NL 427248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " UpdateBuffer0(id, g_add_value);" NL " if (id == uvec3(1, g_counter_y, 1)) {" NL 427348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " uint idx = atomicCounterIncrement(g_counter[1]);" NL " g_buffer1.data[idx] = idx;" NL 427448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " idx = atomicCounterIncrement(g_counter[1]);" NL " g_buffer1.data[idx] = idx;" NL " }" NL 427548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " if (id.x < 4 && id.y < 4 && id.z == 0) {" NL 427648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " vec4 v = imageLoad(g_image0, ivec2(id.xy));" NL 427748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " imageStore(g_image0, ivec2(id.xy), v + g_image_value);" NL " }" NL 427848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " if (id.x < 2 && id.y == 0 && id.z == 0) {" NL " g_buffer2.data[id.x] -= int(g_counter_y);" NL 427948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " }" NL "}"; 428048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 428148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else if (p == 1) 428248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 428348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos ss << NL "layout(local_size_x = 4, local_size_y = 4, local_size_z = 1) in;" 428448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos // translation matrix 428548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos NL "uniform mat4 g_mvp = mat4(1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 10.0, " 428648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "20.0, 30.0, 1.0);" NL "void main() {" NL " if (gl_GlobalInvocationID == uvec3(0)) {" NL 428748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " g_buffer4.data0 *= g_mvp;" NL " }" NL " if (gl_WorkGroupID == uvec3(0)) {" NL 428848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " g_buffer4.data1[gl_LocalInvocationID.y][gl_LocalInvocationID.x] = " 428948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "g_mvp[gl_LocalInvocationID.x][gl_LocalInvocationID.y];" NL " }" NL "}"; 429048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 429148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else if (p == 2) 429248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 429348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos ss << NL "layout(local_size_x = 4, local_size_y = 4, local_size_z = 4) in;" NL "void main() {" NL "}"; 429448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 429548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ss.str(); 429648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 429748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Setup() 429848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 429948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos memset(m_program, 0, sizeof(m_program)); 430048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos memset(m_storage_buffer, 0, sizeof(m_storage_buffer)); 430148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_counter_buffer = 0; 430248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_texture = 0; 430348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 430448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 430548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Run() 430648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 430748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos using namespace tcu; 430848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 430948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (int i = 0; i < 3; ++i) 431048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 431148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_program[i] = CreateComputeProgram(GenGLSL(i)); 431248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glLinkProgram(m_program[i]); 431348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!CheckProgram(m_program[i])) 431448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 431548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 431648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 431748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGenBuffers(4, m_storage_buffer); 431848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* storage buffer 0 */ 431948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 432048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::vector<int> data(5 + 8 * 8 * 8); 432148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_storage_buffer[0]); 432248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBufferData(GL_SHADER_STORAGE_BUFFER, (GLsizeiptr)(data.size() * sizeof(int)), &data[0], GL_STATIC_COPY); 432348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 432448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* storage buffer 1 */ 432548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 432648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLuint data[8] = { 0 }; 432748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_storage_buffer[1]); 432848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), data, GL_STATIC_COPY); 432948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 433048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* storage buffer 2 & 3 */ 433148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 433248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::vector<GLint> data(512, 7); 433348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer[2]); 433448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBufferData(GL_SHADER_STORAGE_BUFFER, (GLsizeiptr)(data.size() * sizeof(GLint)), &data[0], GL_STATIC_COPY); 433548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 433648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBufferRange(GL_SHADER_STORAGE_BUFFER, 2, m_storage_buffer[2], 0, 433748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos (GLsizeiptr)(sizeof(GLint) * data.size() / 2)); 433848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBufferRange(GL_SHADER_STORAGE_BUFFER, 3, m_storage_buffer[2], 433948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos (GLintptr)(sizeof(GLint) * data.size() / 2), 434048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos (GLsizeiptr)(sizeof(GLint) * data.size() / 2)); 434148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 434248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* storage buffer 4 */ 434348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 434448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::vector<mat4> data(2); 434548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos data[0] = mat4(1); 434648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, m_storage_buffer[3]); 434748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBufferData(GL_SHADER_STORAGE_BUFFER, (GLsizeiptr)(data.size() * sizeof(mat4)), &data[0], GL_STATIC_COPY); 434848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 434948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* counter buffer */ 435048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 435148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint data[4] = { 0 }; 435248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGenBuffers(1, &m_counter_buffer); 435348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 1, m_counter_buffer); 435448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBufferData(GL_ATOMIC_COUNTER_BUFFER, sizeof(data), data, GL_STATIC_COPY); 435548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 435648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* texture */ 435748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 435848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::vector<vec4> data(4 * 4, vec4(0.0f)); 435948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGenTextures(1, &m_texture); 436048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindTexture(GL_TEXTURE_2D, m_texture); 436148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 436248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 436348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, 4, 4, 0, GL_RGBA, GL_FLOAT, &data[0]); 436448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindTexture(GL_TEXTURE_2D, 0); 436548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 436648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 436748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUseProgram(m_program[0]); 436848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindImageTexture(0, m_texture, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32F); 436948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDispatchCompute(2, 2, 2); 437048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT | GL_SHADER_IMAGE_ACCESS_BARRIER_BIT); 437148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDispatchCompute(3, 2, 2); 437248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 437348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUseProgram(m_program[1]); 437448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDispatchCompute(4, 3, 7); 437548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 437648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT | GL_TEXTURE_UPDATE_BARRIER_BIT | 437748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GL_SHADER_IMAGE_ACCESS_BARRIER_BIT); 437848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 437948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* validate texture */ 438048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 438148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::vector<vec4> data(4 * 4); 438248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindTexture(GL_TEXTURE_2D, m_texture); 438348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGenFramebuffers(1, &m_fbo); 438448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindFramebuffer(GL_FRAMEBUFFER, m_fbo); 438548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_texture, 0); 438648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::vector<GLubyte> colorData(4 * 4 * 4); 438748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glReadPixels(0, 0, 4, 4, GL_RGBA, GL_UNSIGNED_BYTE, &colorData[0]); 438848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (int i = 0; i < 4 * 4 * 4; i += 4) 438948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 439048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos data[i / 4] = 439148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos vec4(static_cast<GLfloat>(colorData[i] / 255.), static_cast<GLfloat>(colorData[i + 1] / 255.), 439248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static_cast<GLfloat>(colorData[i + 2] / 255.), static_cast<GLfloat>(colorData[i + 3] / 255.)); 439348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 439448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (std::size_t i = 0; i < data.size(); ++i) 439548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 439648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!ColorEqual(data[i], vec4(0.25f, 0.5f, 0.75f, 1.0f), g_color_eps)) 439748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 4398910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() 4399910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << tcu::TestLog::Message << "Invalid data at texture." << tcu::TestLog::EndMessage; 440048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 440148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 440248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 440348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 440448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* validate storage buffer 0 */ 440548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 440648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::vector<int> data(5 + 8 * 8 * 8); 440748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer[0]); 440848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, (GLsizeiptr)(data.size() * sizeof(int)), &data[0]); 440948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (std::size_t i = 5; i < data.size(); ++i) 441048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 441148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (data[i] != 4) 441248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 4413910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() << tcu::TestLog::Message << "Data is " << data[i] 4414910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << " should be 2." << tcu::TestLog::EndMessage; 441548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 441648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 441748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 441848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 441948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* validate storage buffer 1 */ 442048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 442148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint data[8]; 442248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer[1]); 442348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, sizeof(data), data); 442448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLuint i = 0; i < 4; ++i) 442548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 442648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (data[i] != i) 442748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 4428910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() << tcu::TestLog::Message << "Data is " << data[i] 4429910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << " should be " << i << "." << tcu::TestLog::EndMessage; 443048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 443148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 443248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 443348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 443448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* validate storage buffer 2 & 3 */ 443548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 443648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::vector<GLint> data(512); 443748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer[2]); 443848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, (GLsizeiptr)(sizeof(GLint) * data.size()), &data[0]); 443948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (int i = 0; i < 2; ++i) 444048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 444148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (data[i] != 5) 444248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 4443910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() << tcu::TestLog::Message << "Data is: " << data[i] 4444910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << " should be: 5." << tcu::TestLog::EndMessage; 444548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 444648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 444748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (data[i + 256] != 7) 444848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 4449910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() << tcu::TestLog::Message << "Data is: " << data[i + 256] 4450910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << " should be: 7." << tcu::TestLog::EndMessage; 445148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 445248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 445348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 445448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 445548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* validate storage buffer 4 */ 445648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 445748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos mat4 data[2]; 445848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer[3]); 445948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, sizeof(data), &data[0](0, 0)); 4460fe6a4d09be7c3502c95107cddd05cb41e193c38dNicolai Hähnle if (data[0] != translationMatrix(vec3(10.0f, 20.0f, 30.0f))) 446148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 4462910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() 4463910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << tcu::TestLog::Message << "Data is incorrect." << tcu::TestLog::EndMessage; 446448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 446548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 4466fe6a4d09be7c3502c95107cddd05cb41e193c38dNicolai Hähnle if (data[1] != transpose(translationMatrix(vec3(10.0f, 20.0f, 30.0f)))) 446748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 4468910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() 4469910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << tcu::TestLog::Message << "Data is incorrect." << tcu::TestLog::EndMessage; 447048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 447148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 447248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 447348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* validate counter buffer */ 447448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 447548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint data[4] = { 0 }; 447648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetBufferSubData(GL_ATOMIC_COUNTER_BUFFER, 0, sizeof(data), data); 447748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (data[3] != 4) 447848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 4479910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() 4480910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << tcu::TestLog::Message << "Data is: " << data[3] << " should be: 4." << tcu::TestLog::EndMessage; 448148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 448248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 448348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 448448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 448548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 448648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 448748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Cleanup() 448848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 448948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUseProgram(0); 449048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (int i = 0; i < 3; ++i) 449148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteProgram(m_program[i]); 449248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteBuffers(4, m_storage_buffer); 449348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteBuffers(1, &m_counter_buffer); 449448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteTextures(1, &m_texture); 449548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteFramebuffers(1, &m_fbo); 449648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 449748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 449848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}; 449948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 450048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosclass AdvancedPipelinePostFS : public ComputeShaderBase 450148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 450248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Title() 450348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 450448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "CS as an additional pipeline stage - After FS"; 450548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 450648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Purpose() 450748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 450848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "1. Verify that CS which runs just after FS to do a post-processing on a rendered image works as " 450948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "expected." NL "2. Verify that CS used as a post-processing filter works as expected." NL 451048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "3. Verify that several CS kernels which run in a sequence to do a post-processing on a rendered " 451148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "image works as expected."; 451248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 451348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Method() 451448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 451548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL 451648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "1. Render image to Texture0 using VS and FS." NL 451748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "2. Use Texture0 as an input to Kernel0 which performs post-processing and writes result to Texture1." NL 451848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "3. Issue MemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT) command." NL 451948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "4. Use Texture1 as an input to Kernel1 which performs post-processing and writes result to Texture0." NL 452048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "5. Issue MemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT) command." NL 452148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "6. Verify content of the final post-processed image (Texture0)."; 452248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 452348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string PassCriteria() 452448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 452548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "Everything works as expected."; 452648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 452748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 452848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_program[3]; 452948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_render_target[2]; 453048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_framebuffer; 453148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_vertex_array; 453248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 453348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Setup() 453448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 453548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos memset(m_program, 0, sizeof(m_program)); 453648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos memset(m_render_target, 0, sizeof(m_render_target)); 453748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_framebuffer = 0; 453848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_vertex_array = 0; 453948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 454048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 454148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 454248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Run() 454348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 454448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* const glsl_vs = 454548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos NL "const vec2 g_vertex[4] = vec2[4](vec2(0), vec2(-1, -1), vec2(3, -1), vec2(-1, 3));" NL 454648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void main() {" NL " gl_Position = vec4(g_vertex[gl_VertexID], 0, 1);" NL "}"; 454748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 454848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* const glsl_fs = 454948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos NL "layout(location = 0) out vec4 g_color;" NL "void main() {" NL " g_color = vec4(1, 0, 0, 1);" NL "}"; 455048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 455148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_program[0] = CreateProgram(glsl_vs, glsl_fs); 455248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glLinkProgram(m_program[0]); 455348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!CheckProgram(m_program[0])) 455448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 455548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 455648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* const glsl_cs = 455748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos NL "#define TILE_WIDTH 16" NL "#define TILE_HEIGHT 16" NL 455848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "const ivec2 kTileSize = ivec2(TILE_WIDTH, TILE_HEIGHT);" NL NL 455948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "layout(binding = 0, rgba32f) uniform image2D g_input_image;" NL 456048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "layout(binding = 1, rgba32f) uniform image2D g_output_image;" NL NL 456148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "layout(local_size_x = TILE_WIDTH, local_size_y=TILE_HEIGHT) in;" NL NL "void main() {" NL 456248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " const ivec2 tile_xy = ivec2(gl_WorkGroupID);" NL 456348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " const ivec2 thread_xy = ivec2(gl_LocalInvocationID);" NL NL " if (thread_xy == ivec2(0)) {" NL 456448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " const ivec2 pixel_xy = tile_xy * kTileSize;" NL " for (int y = 0; y < TILE_HEIGHT; ++y) {" NL 456548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " for (int x = 0; x < TILE_WIDTH; ++x) {" NL 456648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " imageStore(g_output_image, pixel_xy + ivec2(x, y), vec4(0, 1, 0, 1));" NL " }" NL 456748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " }" NL " }" NL "}"; 456848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 456948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_program[1] = CreateComputeProgram(glsl_cs); 457048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glLinkProgram(m_program[1]); 457148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!CheckProgram(m_program[1])) 457248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 457348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 457448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* const glsl_cs2 = NL "#define TILE_WIDTH 32" NL "#define TILE_HEIGHT 32" NL 457548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "const ivec2 kTileSize = ivec2(TILE_WIDTH, TILE_HEIGHT);" NL NL 457648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "layout(binding = 0, rgba32f) uniform image2D g_input_image;" NL 457748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "layout(binding = 1, rgba32f) uniform image2D g_output_image;" NL NL 457848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "layout(local_size_x = TILE_WIDTH, local_size_y=TILE_HEIGHT) in;" NL NL 457948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "vec4 Process(vec4 ic) {" NL " return ic + vec4(1, 0, 0, 0);" NL "}" NL 458048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void main() {" NL " const ivec2 tile_xy = ivec2(gl_WorkGroupID);" NL 458148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " const ivec2 thread_xy = ivec2(gl_LocalInvocationID);" NL 458248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " const ivec2 pixel_xy = tile_xy * kTileSize + thread_xy;" NL 458348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " vec4 ic = imageLoad(g_input_image, pixel_xy);" NL 458448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " imageStore(g_output_image, pixel_xy, Process(ic));" NL "}"; 458548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_program[2] = CreateComputeProgram(glsl_cs2); 458648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glLinkProgram(m_program[2]); 458748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!CheckProgram(m_program[2])) 458848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 458948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 459048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGenVertexArrays(1, &m_vertex_array); 459148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 459248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* init render targets */ 459348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 459448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::vector<vec4> data(128 * 128); 459548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGenTextures(2, m_render_target); 459648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (int i = 0; i < 2; ++i) 459748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 459848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindTexture(GL_TEXTURE_2D, m_render_target[i]); 459948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 460048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, 128, 128, 0, GL_RGBA, GL_FLOAT, &data[0][0]); 460148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 460248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindTexture(GL_TEXTURE_2D, 0); 460348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 460448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 460548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGenFramebuffers(1, &m_framebuffer); 460648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindFramebuffer(GL_FRAMEBUFFER, m_framebuffer); 460748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_render_target[0], 0); 460848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindFramebuffer(GL_FRAMEBUFFER, 0); 460948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 461048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindFramebuffer(GL_FRAMEBUFFER, m_framebuffer); 461148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUseProgram(m_program[0]); 461248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindVertexArray(m_vertex_array); 461348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glClear(GL_COLOR_BUFFER_BIT); 461448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glViewport(0, 0, 128, 128); 461548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos // draw full-viewport triangle 461648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDrawArrays(GL_TRIANGLES, 1, 461748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 3); // note: <first> is 1 this means that gl_VertexID in the VS will be: 1, 2 and 3 461848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindFramebuffer(GL_FRAMEBUFFER, 0); 461948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 462048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindImageTexture(0, m_render_target[0], 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA32F); // input 462148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindImageTexture(1, m_render_target[1], 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA32F); // output 462248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUseProgram(m_program[1]); 462348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDispatchCompute(128 / 16, 128 / 16, 1); 462448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 462548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindImageTexture(0, m_render_target[1], 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA32F); // input 462648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindImageTexture(1, m_render_target[0], 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA32F); // output 462748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUseProgram(m_program[2]); 462848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT); 462948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDispatchCompute(128 / 32, 128 / 32, 1); 463048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 463148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* validate render target */ 463248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 463348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::vector<vec4> data(128 * 128); 463448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindTexture(GL_TEXTURE_2D, m_render_target[0]); 463548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glMemoryBarrier(GL_TEXTURE_UPDATE_BARRIER_BIT); 463648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_FLOAT, &data[0][0]); 463748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (std::size_t i = 0; i < data.size(); ++i) 463848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 463948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!IsEqual(data[i], vec4(1, 1, 0, 1))) 464048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 4641910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() 4642910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << tcu::TestLog::Message << "Invalid data at index " << i << "." << tcu::TestLog::EndMessage; 464348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 464448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 464548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 464648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 464748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 464848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 464948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 465048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Cleanup() 465148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 465248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glViewport(0, 0, getWindowWidth(), getWindowHeight()); 465348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUseProgram(0); 465448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (int i = 0; i < 3; ++i) 465548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteProgram(m_program[i]); 465648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteTextures(2, m_render_target); 465748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteVertexArrays(1, &m_vertex_array); 465848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteFramebuffers(1, &m_framebuffer); 465948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 466048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 466148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}; 466248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 466348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosclass AdvancedPipelinePostXFB : public ComputeShaderBase 466448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 466548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Title() 466648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 466748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "CS as an additional pipeline stage - After XFB"; 466848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 466948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Purpose() 467048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 467148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "1. Verify that CS which process data fedback by VS works as expected." NL 467248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "2. Verify that XFB and SSBO works correctly together in one shader." NL 467348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "3. Verify that 'switch' statment which selects different execution path for each CS thread works as " 467448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "expected."; 467548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 467648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Method() 467748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 467848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "1. Draw triangle with XFB enabled. Some data is written to the XFB buffer." NL 467948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "2. Use XFB buffer as 'input SSBO' in CS. Process data and write it to 'output SSBO'." NL 468048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "3. Verify 'output SSBO' content."; 468148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 468248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string PassCriteria() 468348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 468448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "Everything works as expected."; 468548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 468648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 468748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_program[2]; 468848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_storage_buffer; 468948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_xfb_buffer; 469048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_vertex_buffer; 469148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_vertex_array; 469248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 469348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Setup() 469448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 469548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos memset(m_program, 0, sizeof(m_program)); 469648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_storage_buffer = 0; 469748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_xfb_buffer = 0; 469848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_vertex_buffer = 0; 469948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_vertex_array = 0; 470048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 470148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 470248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Run() 470348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 470448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLint res; 470548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetIntegerv(GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS, &res); 470648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (res <= 0) 470748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 470848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos OutputNotSupported("GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS <= 0"); 470948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 471048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 471148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 471248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* const glsl_vs = 471348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos NL "layout(location = 0) in vec4 g_position;" NL "layout(location = 1) in vec4 g_color;" NL 471448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "struct Vertex {" NL " vec4 position;" NL " vec4 color;" NL "};" NL "out StageData {" NL 471548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " vec4 color;" NL "} g_vs_out;" NL "layout(binding = 0, std430) buffer StageData {" NL 471648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " Vertex vertex[];" NL "} g_vs_buffer;" NL "void main() {" NL " gl_Position = g_position;" NL 471748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " g_vs_out.color = g_color;" NL " g_vs_buffer.vertex[gl_VertexID].position = g_position;" NL 471848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " g_vs_buffer.vertex[gl_VertexID].color = g_color;" NL "}"; 471948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 472048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* const glsl_fs = 472148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos NL "in StageData {" NL " vec4 color;" NL "} g_fs_in;" NL "layout(location = 0) out vec4 g_color;" NL 472248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void main() {" NL " g_color = g_fs_in.color;" NL "}"; 472348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 472448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_program[0] = CreateProgram(glsl_vs, glsl_fs); 472548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* setup xfb varyings */ 472648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 472748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* const var[2] = { "gl_Position", "StageData.color" }; 472848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glTransformFeedbackVaryings(m_program[0], 2, var, GL_INTERLEAVED_ATTRIBS); 472948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 473048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glLinkProgram(m_program[0]); 473148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!CheckProgram(m_program[0])) 473248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 473348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 473448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* const glsl_cs = 473548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos NL "layout(local_size_x = 3) in;" NL "struct Vertex {" NL " vec4 position;" NL " vec4 color;" NL "};" NL 473648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "layout(binding = 3, std430) buffer Buffer {" NL " Vertex g_vertex[3];" NL "};" NL 473748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "uniform vec4 g_color1 = vec4(0, 0, 1, 0);" NL "uniform int g_two = 2;" NL 473848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void UpdateVertex2(int i) {" NL " g_vertex[i].color -= vec4(-1, 1, 0, 0);" NL "}" NL "void main() {" NL 473948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " switch (gl_GlobalInvocationID.x) {" NL 474048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " case 0: g_vertex[gl_GlobalInvocationID.x].color += vec4(1, 0, 0, 0); break;" NL 474148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " case 1: g_vertex[1].color += g_color1; break;" NL " case 2: UpdateVertex2(g_two); break;" NL 474248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " default: return;" NL " }" NL "}"; 474348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_program[1] = CreateComputeProgram(glsl_cs); 474448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glLinkProgram(m_program[1]); 474548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!CheckProgram(m_program[1])) 474648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 474748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 474848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGenBuffers(1, &m_storage_buffer); 474948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_storage_buffer); 475048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBufferData(GL_SHADER_STORAGE_BUFFER, 3 * sizeof(vec4) * 2, NULL, GL_STATIC_COPY); 475148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 475248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGenBuffers(1, &m_xfb_buffer); 475348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_xfb_buffer); 475448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, 3 * sizeof(vec4) * 2, NULL, GL_STREAM_COPY); 475548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 475648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const float in_data[3 * 8] = { -1, -1, 0, 1, 0, 1, 0, 1, 3, -1, 0, 1, 0, 1, 0, 1, -1, 3, 0, 1, 0, 1, 0, 1 }; 475748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGenBuffers(1, &m_vertex_buffer); 475848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBuffer(GL_ARRAY_BUFFER, m_vertex_buffer); 475948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBufferData(GL_ARRAY_BUFFER, sizeof(in_data), in_data, GL_STATIC_DRAW); 476048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBuffer(GL_ARRAY_BUFFER, 0); 476148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 476248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGenVertexArrays(1, &m_vertex_array); 476348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindVertexArray(m_vertex_array); 476448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBuffer(GL_ARRAY_BUFFER, m_vertex_buffer); 476548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 2 * sizeof(vec4), 0); 476648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 2 * sizeof(vec4), reinterpret_cast<void*>(sizeof(vec4))); 476748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBuffer(GL_ARRAY_BUFFER, 0); 476848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glEnableVertexAttribArray(0); 476948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glEnableVertexAttribArray(1); 477048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindVertexArray(0); 477148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 477248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glClear(GL_COLOR_BUFFER_BIT); 477348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUseProgram(m_program[0]); 477448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindVertexArray(m_vertex_array); 477548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBeginTransformFeedback(GL_TRIANGLES); 477648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDrawArrays(GL_TRIANGLES, 0, 3); 477748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glEndTransformFeedback(); 477848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 477948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, m_xfb_buffer); 478048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUseProgram(m_program[1]); 478148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDispatchCompute(1, 1, 1); 478248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 478348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT); 478448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 478548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* validate storage buffer */ 478648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 478748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos float data[3 * 8]; 478848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer); 478948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, sizeof(data), data); 479048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (memcmp(data, in_data, sizeof(data)) != 0) 479148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 4792910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() 4793910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << tcu::TestLog::Message << "Data in shader storage buffer is incorrect." 4794910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << tcu::TestLog::EndMessage; 479548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 479648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 479748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 479848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* validate xfb buffer */ 479948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 480048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const float ref_data[3 * 8] = { 480148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos -1, -1, 0, 1, 1, 1, 0, 1, 3, -1, 0, 1, 0, 1, 1, 1, -1, 3, 0, 1, 1, 0, 0, 1 480248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos }; 480348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 480448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos float data[3 * 8]; 480548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetBufferSubData(GL_TRANSFORM_FEEDBACK_BUFFER, 0, sizeof(data), data); 480648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (memcmp(data, ref_data, sizeof(data)) != 0) 480748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 4808910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() 4809910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << tcu::TestLog::Message << "Data in xfb buffer is incorrect." << tcu::TestLog::EndMessage; 481048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 481148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 481248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 481348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!ValidateReadBuffer(0, 0, getWindowWidth(), getWindowHeight(), vec4(0, 1, 0, 1))) 481448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 481548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 481648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 481748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 481848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 481948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 482048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Cleanup() 482148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 482248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUseProgram(0); 482348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (int i = 0; i < 2; ++i) 482448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteProgram(m_program[i]); 482548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteBuffers(1, &m_vertex_buffer); 482648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteBuffers(1, &m_storage_buffer); 482748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteBuffers(1, &m_xfb_buffer); 482848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteVertexArrays(1, &m_vertex_array); 482948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 483048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 483148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}; 483248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 483348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosclass AdvancedSharedIndexing : public ComputeShaderBase 483448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 483548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Title() 483648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 483748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "Shared Memory - Indexing"; 483848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 483948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Purpose() 484048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 484148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "1. Verify that indexing various types of shared memory works as expected." NL 484248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "2. Verify that indexing shared memory with different types of expressions work as expected." NL 484348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "3. Verify that all declaration types of shared structures are supported by the GLSL compiler."; 484448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 484548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Method() 484648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 484748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "1. Create CS which uses shared memory in many different ways." NL 484848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "2. Write to shared memory using different expressions." NL "3. Validate shared memory content." NL 484948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "4. Use synchronization primitives (barrier, groupMemoryBarrier) where applicable."; 485048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 485148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string PassCriteria() 485248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 485348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "Everyting works as expected."; 485448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 485548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 485648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_program; 485748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_texture; 485848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 485948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Setup() 486048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 486148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_program = 0; 486248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_texture = 0; 486348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 486448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 486548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Run() 486648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 486748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* const glsl_cs = NL 486848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "layout(binding = 3, rgba32f) uniform image2D g_result_image;" NL 486948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "layout (local_size_x = 4,local_size_y=4 ) in;" NL "shared vec4 g_shared1[4];" NL 487048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "shared mat4 g_shared2;" NL "shared struct {" NL " float data[4];" NL "} g_shared3[4];" NL 487148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "shared struct Type { float data[4]; } g_shared4[4];" NL "shared Type g_shared5[4];" NL 487248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "uniform bool g_true = true;" NL 487348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "uniform float g_values[16] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 };" NL NL 487448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void Sync() {" NL " groupMemoryBarrier();" NL " barrier();" NL "}" NL 487548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void SetMemory(ivec2 xy, float value) {" NL " g_shared1[xy.y][gl_LocalInvocationID.x] = value;" NL 487648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " g_shared2[xy.y][xy.x] = value;" NL " g_shared3[xy[1]].data[xy[0]] = value;" NL 487748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " g_shared4[xy.y].data[xy[0]] = value;" NL 487848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " g_shared5[gl_LocalInvocationID.y].data[gl_LocalInvocationID.x] = value;" NL "}" NL 487948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "bool CheckMemory(ivec2 xy, float expected) {" NL 488048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " if (g_shared1[xy.y][xy[0]] != expected) return false;" NL 488148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " if (g_shared2[xy[1]][xy[0]] != expected) return false;" NL 488248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " if (g_shared3[gl_LocalInvocationID.y].data[gl_LocalInvocationID.x] != expected) return false;" NL 488348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " if (g_shared4[gl_LocalInvocationID.y].data[xy.x] != expected) return false;" NL 488448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " if (g_shared5[xy.y].data[xy.x] != expected) return false;" NL " return true;" NL "}" NL 488548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void main() {" NL " const ivec2 thread_xy = ivec2(gl_LocalInvocationID);" NL 488648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " vec4 result = vec4(0, 1, 0, 1);" NL NL 488748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " SetMemory(thread_xy, g_values[gl_LocalInvocationIndex] * 1.0);" NL " Sync();" NL 488848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " if (!CheckMemory(thread_xy, g_values[gl_LocalInvocationIndex] * 1.0)) result = vec4(1, 0, 0, 1);" NL NL 488948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " SetMemory(thread_xy, g_values[gl_LocalInvocationIndex] * -1.0);" NL " Sync();" NL 489048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " if (!CheckMemory(thread_xy, g_values[gl_LocalInvocationIndex] * -1.0)) result = vec4(1, 0, 0, 1);" NL NL 489148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " if (g_true && gl_LocalInvocationID.x < 10) {" NL 489248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " SetMemory(thread_xy, g_values[gl_LocalInvocationIndex] * 7.0);" NL " Sync();" NL 489348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " if (!CheckMemory(thread_xy, g_values[gl_LocalInvocationIndex] * 7.0)) result = vec4(1, 0, 0, 1);" NL 489448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " }" NL NL " imageStore(g_result_image, thread_xy, result);" NL "}"; 489548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_program = CreateComputeProgram(glsl_cs); 489648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glLinkProgram(m_program); 489748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!CheckProgram(m_program)) 489848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 489948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 490048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* init texture */ 490148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 490248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::vector<vec4> data(4 * 4); 490348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGenTextures(1, &m_texture); 490448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindTexture(GL_TEXTURE_2D, m_texture); 490548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 490648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, 4, 4, 0, GL_RGBA, GL_FLOAT, &data[0][0]); 490748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindTexture(GL_TEXTURE_2D, 0); 490848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 490948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 491048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindImageTexture(3, m_texture, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA32F); 491148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUseProgram(m_program); 491248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDispatchCompute(1, 1, 1); 491348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 491448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* validate render target */ 491548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 491648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::vector<vec4> data(4 * 4); 491748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindTexture(GL_TEXTURE_2D, m_texture); 491848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glMemoryBarrier(GL_TEXTURE_UPDATE_BARRIER_BIT); 491948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_FLOAT, &data[0][0]); 492048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (std::size_t i = 0; i < data.size(); ++i) 492148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 492248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!IsEqual(data[i], vec4(0, 1, 0, 1))) 492348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 4924910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() 4925910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << tcu::TestLog::Message << "Invalid data at index " << i << "." << tcu::TestLog::EndMessage; 492648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 492748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 492848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 492948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 493048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 493148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 493248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Cleanup() 493348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 493448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUseProgram(0); 493548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteProgram(m_program); 493648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteTextures(1, &m_texture); 493748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 493848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 493948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}; 494048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 494148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosclass AdvancedSharedMax : public ComputeShaderBase 494248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 494348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Title() 494448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 494548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "Shared Memory - 32K"; 494648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 494748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Purpose() 494848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 494948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "Support for 32K of shared memory is required by the OpenGL specifaction. Verify if an " 495048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "implementation supports it."; 495148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 495248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Method() 495348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 495448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "Create and dispatch CS which uses 32K of shared memory."; 495548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 495648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string PassCriteria() 495748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 495848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "Everything works as expected."; 495948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 496048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 496148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_program; 496248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_buffer; 496348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 496448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Setup() 496548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 496648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_program = 0; 496748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_buffer = 0; 496848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 496948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 497048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Run() 497148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 497248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* const glsl_cs = 497348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos NL "layout(local_size_x = 1024) in;" NL 497448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "shared struct Type { vec4 v[2]; } g_shared[1024];" // 32768 bytes of shared memory 497548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos NL "layout(std430) buffer Output {" NL " Type g_output[1024];" NL "};" NL NL "void main() {" NL 497648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " const int id = int(gl_GlobalInvocationID.x);" NL 497748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " g_shared[id].v = vec4[2](vec4(1.0), vec4(1.0));" NL " memoryBarrierShared();" NL " barrier();" NL NL 497848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " vec4 sum = vec4(0.0);" NL " int sum_count = 0;" NL " for (int i = id - 3; i < id + 4; ++i) {" NL 497948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " if (id >= 0 && id < g_shared.length()) {" NL " sum += g_shared[id].v[0];" NL 498048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " sum += g_shared[id].v[1];" NL " sum_count += 2;" NL " }" NL " }" NL 498148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " if (any(greaterThan(abs((sum / sum_count) - vec4(1.0)), vec4(0.0000001f)))) return;" NL NL 498248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " g_output[id] = g_shared[id];" NL "}"; 498348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_program = CreateComputeProgram(glsl_cs); 498448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glLinkProgram(m_program); 498548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!CheckProgram(m_program)) 498648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 498748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 498848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* init buffer */ 498948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 499048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::vector<vec4> data(1024 * 2); 499148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGenBuffers(1, &m_buffer); 499248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_buffer); 499348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBufferData(GL_SHADER_STORAGE_BUFFER, (GLsizeiptr)(sizeof(vec4) * data.size()), &data[0][0], 499448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GL_DYNAMIC_COPY); 499548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 499648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 499748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUseProgram(m_program); 499848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDispatchCompute(1, 1, 1); 499948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT); 500048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 500148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* validate buffer */ 500248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 500348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::vector<vec4> data(1024 * 2); 500448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, (GLsizeiptr)(sizeof(vec4) * data.size()), &data[0][0]); 500548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (std::size_t i = 0; i < data.size(); ++i) 500648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 500748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!IsEqual(data[i], vec4(1.0f))) 500848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 5009910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() 5010910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << tcu::TestLog::Message << "Invalid data at index " << i << "." << tcu::TestLog::EndMessage; 501148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 501248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 501348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 501448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 501548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 501648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 501748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Cleanup() 501848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 501948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUseProgram(0); 502048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteProgram(m_program); 502148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteBuffers(1, &m_buffer); 502248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 502348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 502448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}; 502548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 502648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosclass AdvancedDynamicPaths : public ComputeShaderBase 502748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 502848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Title() 502948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 503048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "Dynamic execution paths"; 503148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 503248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Purpose() 503348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 503448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "1. Verify case where each of the four threads takes different execution path in the CS." NL 503548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "2. Execution path for each thread is not known at the compilation time." NL 503648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " Selection is made based on the result of the texture sampling." NL 503748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "3. Verify that memory synchronization primitives (memoryBarrier* functions) are accepted" NL 503848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " in the control flow."; 503948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 504048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Method() 504148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 504248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "1. Create and dispatch CS that takes different execution paths based on the result of the texture " 504348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "sampling." NL "2. In each execution path use different resources (buffers, samplers, uniform " 504448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "arrays) to compute output value."; 504548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 504648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string PassCriteria() 504748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 504848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "Everything works as expected."; 504948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 505048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 505148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_program; 505248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_buffer[4]; 505348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_texture[2]; 505448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 505548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Setup() 505648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 505748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_program = 0; 505848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos memset(m_buffer, 0, sizeof(m_buffer)); 505948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos memset(m_texture, 0, sizeof(m_texture)); 506048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 506148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 506248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Run() 506348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 506448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* const glsl_cs = 506548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos NL "layout(local_size_x = 4) in;" NL "layout(std140, binding = 0) buffer Output {" NL 506648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " vec4 g_output[4];" NL "};" NL "uniform isamplerBuffer g_path_buffer;" NL 506748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "uniform vec4[4] g_input0 = vec4[4](vec4(100), vec4(200), vec4(300), vec4(400));" NL 506848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "uniform samplerBuffer g_input1;" NL "layout(binding = 1, std430) buffer Input2 {" NL 506948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " vec4[4] g_input2;" NL "};" NL NL "void Path2(int id) {" NL 507048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " g_output[id] = texelFetch(g_input1, int(gl_LocalInvocationIndex));" NL "}" NL "void main() {" NL 507148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " const int id = int(gl_GlobalInvocationID.x);" NL 507248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " const int path = texelFetch(g_path_buffer, id).x;" NL NL " if (path == 0) {" NL 507348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " g_output[id] = g_input0[gl_LocalInvocationID.x];" NL " memoryBarrier();" NL 507448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " } else if (path == 1) {" NL " return;" NL " } else if (path == 2) {" NL " Path2(id);" NL 507548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " return;" NL " } else if (path == 3) {" NL " g_output[id] = g_input2[path - 1];" NL 507648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " memoryBarrierBuffer();" NL " }" NL "}"; 507748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_program = CreateComputeProgram(glsl_cs); 507848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glLinkProgram(m_program); 507948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!CheckProgram(m_program)) 508048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 508148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 508248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGenBuffers(4, m_buffer); 508348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGenTextures(2, m_texture); 508448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 508548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* init 'output' buffer */ 508648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 508748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::vector<vec4> data(4, vec4(-100.0f)); 508848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_buffer[0]); 508948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBufferData(GL_SHADER_STORAGE_BUFFER, (GLsizeiptr)(sizeof(vec4) * data.size()), &data[0][0], 509048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GL_DYNAMIC_COPY); 509148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 509248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* init 'input2' buffer */ 509348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 509448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const vec4 data[4] = { vec4(1.0f), vec4(2.0f), vec4(3.0f), vec4(4.0f) }; 509548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_buffer[1]); 509648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), &data[0][0], GL_DYNAMIC_COPY); 509748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 509848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* init 'path' buffer */ 509948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 510048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const int data[4] = { 3, 2, 1, 0 }; 510148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBuffer(GL_TEXTURE_BUFFER, m_buffer[2]); 510248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBufferData(GL_TEXTURE_BUFFER, sizeof(data), &data[0], GL_STATIC_DRAW); 510348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBuffer(GL_TEXTURE_BUFFER, 0); 510448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindTexture(GL_TEXTURE_BUFFER, m_texture[0]); 510548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glTexBuffer(GL_TEXTURE_BUFFER, GL_R32I, m_buffer[2]); 510648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindTexture(GL_TEXTURE_BUFFER, 0); 510748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 510848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* init 'input1' buffer */ 510948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 511048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const vec4 data[4] = { vec4(10.0f), vec4(20.0f), vec4(30.0f), vec4(40.0f) }; 511148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBuffer(GL_TEXTURE_BUFFER, m_buffer[3]); 511248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBufferData(GL_TEXTURE_BUFFER, sizeof(data), &data[0], GL_STATIC_DRAW); 511348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBuffer(GL_TEXTURE_BUFFER, 0); 511448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindTexture(GL_TEXTURE_BUFFER, m_texture[1]); 511548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA32F, m_buffer[3]); 511648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindTexture(GL_TEXTURE_BUFFER, 0); 511748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 511848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 511948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUseProgram(m_program); 512048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUniform1i(glGetUniformLocation(m_program, "g_path_buffer"), 0); 512148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUniform1i(glGetUniformLocation(m_program, "g_input1"), 1); 512248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glActiveTexture(GL_TEXTURE0); 512348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindTexture(GL_TEXTURE_BUFFER, m_texture[0]); 512448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glActiveTexture(GL_TEXTURE1); 512548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindTexture(GL_TEXTURE_BUFFER, m_texture[1]); 512648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDispatchCompute(1, 1, 1); 512748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT); 512848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 512948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* validate 'output' buffer */ 513048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 513148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos vec4 data[4]; 513248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_buffer[0]); 513348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, sizeof(data), &data[0][0]); 513448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 513548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const vec4 expected[4] = { vec4(3.0f), vec4(20.0f), vec4(-100.0f), vec4(400.0f) }; 513648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (int i = 0; i < 4; ++i) 513748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 513848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!IsEqual(data[i], expected[i])) 513948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 5140910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() 5141910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << tcu::TestLog::Message << "Invalid data at index " << i << "." << tcu::TestLog::EndMessage; 514248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 514348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 514448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 514548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 514648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 514748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 514848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Cleanup() 514948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 515048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUseProgram(0); 515148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteProgram(m_program); 515248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteBuffers(4, m_buffer); 515348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteTextures(2, m_texture); 515448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 515548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 515648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}; 515748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 515848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosclass AdvancedResourcesMax : public ComputeShaderBase 515948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 516048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Title() 516148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 516248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "Maximum number of resources in one shader"; 516348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 516448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Purpose() 516548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 516648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "1. Verify that using 8 SSBOs, 12 UBOs, 8 atomic counters, 16 samplers" NL 516748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " and 8 images in one CS works as expected."; 516848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 516948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Method() 517048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 517148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "Create and dispatch CS. Verify result."; 517248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 517348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string PassCriteria() 517448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 517548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "Everything works as expected."; 517648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 517748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 517848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_program; 517948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_storage_buffer[8]; 518048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_uniform_buffer[12]; 518148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_atomic_buffer[8]; 518248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_texture_buffer[16]; 518348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_texture[16]; 518448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_image_buffer[8]; 518548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_image[8]; 518648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 518748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos bool RunIteration(GLuint index) 518848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 518948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLuint i = 0; i < 8; ++i) 519048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 519148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLuint data = i + 1; 519248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBufferBase(GL_SHADER_STORAGE_BUFFER, i, m_storage_buffer[i]); 519348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), &data, GL_STATIC_DRAW); 519448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 519548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLuint i = 0; i < 12; ++i) 519648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 519748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLuint data = i + 1; 519848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBufferBase(GL_UNIFORM_BUFFER, i, m_uniform_buffer[i]); 519948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBufferData(GL_UNIFORM_BUFFER, sizeof(data), &data, GL_STATIC_DRAW); 520048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 520148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLuint i = 0; i < 8; ++i) 520248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 520348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLuint data = i + 1; 520448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, i, m_atomic_buffer[i]); 520548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBufferData(GL_ATOMIC_COUNTER_BUFFER, sizeof(data), &data, GL_STATIC_DRAW); 520648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 520748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLuint i = 0; i < 16; ++i) 520848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 520948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLuint data = i + 1; 521048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBuffer(GL_TEXTURE_BUFFER, m_texture_buffer[i]); 521148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBufferData(GL_TEXTURE_BUFFER, sizeof(data), &data, GL_DYNAMIC_READ); 521248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBuffer(GL_TEXTURE_BUFFER, 0); 521348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 521448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glActiveTexture(GL_TEXTURE0 + i); 521548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindTexture(GL_TEXTURE_BUFFER, m_texture[i]); 521648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glTexBuffer(GL_TEXTURE_BUFFER, GL_R32UI, m_texture_buffer[i]); 521748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 521848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLuint i = 0; i < 8; ++i) 521948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 522048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLuint data = i + 1; 522148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBuffer(GL_TEXTURE_BUFFER, m_image_buffer[i]); 522248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBufferData(GL_TEXTURE_BUFFER, sizeof(data), &data, GL_DYNAMIC_COPY); 522348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBuffer(GL_TEXTURE_BUFFER, 0); 522448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 522548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindTexture(GL_TEXTURE_BUFFER, m_image[i]); 522648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glTexBuffer(GL_TEXTURE_BUFFER, GL_R32UI, m_image_buffer[i]); 522748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindTexture(GL_TEXTURE_BUFFER, 0); 522848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 522948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindImageTexture(i, m_image[i], 0, GL_FALSE, 0, GL_READ_ONLY, GL_R32UI); 523048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 523148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 523248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUseProgram(m_program); 523348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUniform1ui(glGetUniformLocation(m_program, "g_index"), index); 523448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* uniform array */ 523548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 523648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::vector<GLuint> data(480); 523748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLuint i = 0; i < static_cast<GLuint>(data.size()); ++i) 523848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos data[i] = i + 1; 523948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUniform1uiv(glGetUniformLocation(m_program, "g_uniform_def"), static_cast<GLsizei>(data.size()), 524048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos &data[0]); 524148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 524248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDispatchCompute(1, 1, 1); 524348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT); 524448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 524548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos bool result = true; 524648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* validate buffer */ 524748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 524848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint data; 524948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer[index]); 525048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, sizeof(data), &data); 525148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 525248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (data != (index + 1) * 6) 525348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 5254910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() << tcu::TestLog::Message << "Data is " << data << " should be " 5255910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << (index + 1) * 6 << "." << tcu::TestLog::EndMessage; 525648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = false; 525748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 525848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0); 525948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 526048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return result; 526148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 526248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Setup() 526348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 526448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_program = 0; 526548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos memset(m_storage_buffer, 0, sizeof(m_storage_buffer)); 526648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos memset(m_uniform_buffer, 0, sizeof(m_uniform_buffer)); 526748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos memset(m_atomic_buffer, 0, sizeof(m_atomic_buffer)); 526848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos memset(m_texture_buffer, 0, sizeof(m_texture_buffer)); 526948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos memset(m_texture, 0, sizeof(m_texture)); 527048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos memset(m_image_buffer, 0, sizeof(m_image_buffer)); 527148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos memset(m_image, 0, sizeof(m_image)); 527248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 527348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 527448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Run() 527548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 527648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* const glsl_cs = 527748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos NL "layout(local_size_x = 1) in;" NL "layout(std140, binding = 0) buffer ShaderStorageBlock {" NL 527848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " uint data;" NL "} g_shader_storage[8];" NL "layout(std140, binding = 0) uniform UniformBlock {" NL 527948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " uint data;" NL "} g_uniform[12];" NL "layout(binding = 0) uniform usamplerBuffer g_sampler[16];" NL 528048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "layout(binding = 0, r32ui) uniform uimageBuffer g_image[8];" NL 528148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "layout(binding = 0, offset = 0) uniform atomic_uint g_atomic_counter0;" NL 528248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "layout(binding = 1, offset = 0) uniform atomic_uint g_atomic_counter1;" NL 528348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "layout(binding = 2, offset = 0) uniform atomic_uint g_atomic_counter2;" NL 528448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "layout(binding = 3, offset = 0) uniform atomic_uint g_atomic_counter3;" NL 528548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "layout(binding = 4, offset = 0) uniform atomic_uint g_atomic_counter4;" NL 528648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "layout(binding = 5, offset = 0) uniform atomic_uint g_atomic_counter5;" NL 528748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "layout(binding = 6, offset = 0) uniform atomic_uint g_atomic_counter6;" NL 528848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "layout(binding = 7, offset = 0) uniform atomic_uint g_atomic_counter7;" NL 528948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "uniform uint g_uniform_def[480];" NL "uniform uint g_index = 0u;" NL NL "uint Add() {" NL 529048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " switch (g_index) {" NL " case 0: return atomicCounter(g_atomic_counter0);" NL 529148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " case 1: return atomicCounter(g_atomic_counter1);" NL 529248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " case 2: return atomicCounter(g_atomic_counter2);" NL 529348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " case 3: return atomicCounter(g_atomic_counter3);" NL 529448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " case 4: return atomicCounter(g_atomic_counter4);" NL 529548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " case 5: return atomicCounter(g_atomic_counter5);" NL 529648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " case 6: return atomicCounter(g_atomic_counter6);" NL 529748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " case 7: return atomicCounter(g_atomic_counter7);" NL " }" NL "}" NL "void main() {" NL 529848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " g_shader_storage[g_index].data += g_uniform[g_index].data;" NL 529948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " g_shader_storage[g_index].data += texelFetch(g_sampler[g_index], 0).x;" NL 530048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " g_shader_storage[g_index].data += imageLoad(g_image[g_index], 0).x;" NL 530148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " g_shader_storage[g_index].data += Add();" NL 530248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " g_shader_storage[g_index].data += g_uniform_def[g_index];" NL "}"; 530348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_program = CreateComputeProgram(glsl_cs); 530448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glLinkProgram(m_program); 530548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!CheckProgram(m_program)) 530648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 530748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 530848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGenBuffers(16, m_storage_buffer); 530948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGenBuffers(12, m_uniform_buffer); 531048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGenBuffers(8, m_atomic_buffer); 531148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGenBuffers(16, m_texture_buffer); 531248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGenTextures(16, m_texture); 531348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGenBuffers(8, m_image_buffer); 531448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGenTextures(8, m_image); 531548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 531648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!RunIteration(0)) 531748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 531848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!RunIteration(1)) 531948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 532048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!RunIteration(5)) 532148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 532248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 532348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 532448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 532548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Cleanup() 532648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 532748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUseProgram(0); 532848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteProgram(m_program); 532948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteBuffers(16, m_storage_buffer); 533048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteBuffers(12, m_uniform_buffer); 533148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteBuffers(8, m_atomic_buffer); 533248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteBuffers(16, m_texture_buffer); 533348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteTextures(16, m_texture); 533448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteBuffers(8, m_image_buffer); 533548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteTextures(8, m_image); 533648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 533748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 533848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}; 533948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 534048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosclass AdvancedFP64Case1 : public ComputeShaderBase 534148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 534248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Title() 534348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 534448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "FP64 support - built-in math functions"; 534548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 534648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Purpose() 534748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 534848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "Verify that selected double precision math functions works as expected in the CS."; 534948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 535048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Method() 535148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 535248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "Create and dispatch CS which uses double precision math functions. Verify results."; 535348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 535448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string PassCriteria() 535548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 535648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "Everything works as expected."; 535748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 535848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 535948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_program; 536048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_storage_buffer[4]; 536148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_uniform_buffer[2]; 536248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 536348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Setup() 536448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 536548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_program = 0; 536648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos memset(m_storage_buffer, 0, sizeof(m_storage_buffer)); 536748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos memset(m_uniform_buffer, 0, sizeof(m_uniform_buffer)); 536848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 536948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 537048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Run() 537148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 537248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* const glsl_cs = 537348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos NL "layout(local_size_x = 4) in;" NL "layout(std140, binding = 0) buffer ShaderStorageBlock {" NL 537448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " double data;" NL "} g_shader_storage[4];" NL "layout(std140, binding = 0) uniform UniformBlock {" NL 537548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " double data;" NL "} g_uniform[2];" NL "uniform dvec2 g_uniform_def;" NL NL "void main() {" NL 537648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " if (gl_GlobalInvocationID.x == 0) {" NL 537748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " g_shader_storage[0].data = floor(g_uniform[0].data + 0.1LF);" // floor(1.1LF) == 1.0LF 537848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos NL " } else if (gl_GlobalInvocationID.x == 1) {" NL 537948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " g_shader_storage[1].data = ceil(g_uniform[1].data + 0.2LF);" // ceil(2.2LF) == 3.0LF 538048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos NL " } else if (gl_GlobalInvocationID.x == 2) {" NL 538148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " g_shader_storage[2].data = min(g_uniform_def[0] + 0.1LF, 1.0LF);" // min(1.1LF, 1.0LF) == 1.0LF 538248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos NL " } else if (gl_GlobalInvocationID.x == 3) {" NL 538348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " g_shader_storage[3].data = max(g_uniform_def[0], g_uniform_def.y);" // max(1.0LF, 2.0LF) == 2.0LF 538448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos NL " }" NL "}"; 538548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_program = CreateComputeProgram(glsl_cs); 538648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glLinkProgram(m_program); 538748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!CheckProgram(m_program)) 538848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 538948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 539048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGenBuffers(4, m_storage_buffer); 539148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLuint i = 0; i < 4; ++i) 539248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 539348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLdouble data = static_cast<GLdouble>(i + 1); 539448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBufferBase(GL_SHADER_STORAGE_BUFFER, i, m_storage_buffer[i]); 539548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), &data, GL_STATIC_DRAW); 539648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 539748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 539848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGenBuffers(2, m_uniform_buffer); 539948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLuint i = 0; i < 2; ++i) 540048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 540148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLdouble data = static_cast<GLdouble>(i + 1); 540248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBufferBase(GL_UNIFORM_BUFFER, i, m_uniform_buffer[i]); 540348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBufferData(GL_UNIFORM_BUFFER, sizeof(data), &data, GL_STATIC_DRAW); 540448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 540548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 540648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUseProgram(m_program); 540748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUniform2d(glGetUniformLocation(m_program, "g_uniform_def"), 1.0, 2.0); 540848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDispatchCompute(1, 1, 1); 540948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT); 541048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 541148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* validate */ 541248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 541348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLdouble expected[4] = { 1.0, 3.0, 1.0, 2.0 }; 541448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (int i = 0; i < 4; ++i) 541548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 541648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLdouble data; 541748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer[i]); 541848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, sizeof(data), &data); 541948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (data != expected[i]) 542048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 5421910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() 5422910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << tcu::TestLog::Message << "Data at index " << i << " is " << data << " should be " 5423910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << expected[i] << "." << tcu::TestLog::EndMessage; 542448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 542548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 542648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 542748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 542848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 542948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 543048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Cleanup() 543148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 543248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUseProgram(0); 543348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteProgram(m_program); 543448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteBuffers(4, m_storage_buffer); 543548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteBuffers(2, m_uniform_buffer); 543648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 543748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 543848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}; 543948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 544048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosclass AdvancedFP64Case2 : public ComputeShaderBase 544148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 544248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Title() 544348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 544448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "FP64 support - uniform variables"; 544548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 544648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Purpose() 544748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 544848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "1. Verify that all types of double precision uniform variables work as expected in CS." NL 544948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "2. Verify that all double precision uniform variables can be updated with Uniform* and " 545048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "ProgramUniform* commands." NL "3. Verify that re-linking CS program works as expected."; 545148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 545248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Method() 545348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 545448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "1. Create CS which uses all (double precision) types of uniform variables." NL 545548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "2. Update uniform variables with ProgramUniform* commands." NL 545648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "3. Verify that uniform variables were updated correctly." NL "4. Re-link CS program." NL 545748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "5. Update uniform variables with Uniform* commands." NL 545848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "6. Verify that uniform variables were updated correctly."; 545948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 546048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string PassCriteria() 546148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 546248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "Everything works as expected."; 546348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 546448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 546548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_program; 546648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_storage_buffer; 546748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 546848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Setup() 546948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 547048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_program = 0; 547148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_storage_buffer = 0; 547248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 547348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 547448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Run() 547548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 547648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* const glsl_cs = NL 547748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "layout(local_size_x = 1) in;" NL "buffer Result {" NL " int g_result;" NL "};" NL "uniform double g_0;" NL 547848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "uniform dvec2 g_1;" NL "uniform dvec3 g_2;" NL "uniform dvec4 g_3;" NL "uniform dmat2 g_4;" NL 547948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "uniform dmat2x3 g_5;" NL "uniform dmat2x4 g_6;" NL "uniform dmat3x2 g_7;" NL "uniform dmat3 g_8;" NL 548048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "uniform dmat3x4 g_9;" NL "uniform dmat4x2 g_10;" NL "uniform dmat4x3 g_11;" NL "uniform dmat4 g_12;" NL NL 548148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void main() {" NL " g_result = 1;" NL NL " if (g_0 != 1.0LF) g_result = 0;" NL 548248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " if (g_1 != dvec2(2.0LF, 3.0LF)) g_result = 0;" NL 548348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " if (g_2 != dvec3(4.0LF, 5.0LF, 6.0LF)) g_result = 0;" NL 548448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " if (g_3 != dvec4(7.0LF, 8.0LF, 9.0LF, 10.0LF)) g_result = 0;" NL NL 548548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " if (g_4 != dmat2(11.0LF, 12.0LF, 13.0LF, 14.0LF)) g_result = 0;" NL 548648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " if (g_5 != dmat2x3(15.0LF, 16.0LF, 17.0LF, 18.0LF, 19.0LF, 20.0LF)) g_result = 0;" NL 548748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " if (g_6 != dmat2x4(21.0LF, 22.0LF, 23.0LF, 24.0LF, 25.0LF, 26.0LF, 27.0LF, 28.0LF)) g_result = 0;" NL NL 548848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " if (g_7 != dmat3x2(29.0LF, 30.0LF, 31.0LF, 32.0LF, 33.0LF, 34.0LF)) g_result = 0;" NL 548948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " if (g_8 != dmat3(35.0LF, 36.0LF, 37.0LF, 38.0LF, 39.0LF, 40.0LF, 41.0LF, 42.0LF, 43.0LF)) g_result = " 549048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "0;" NL " if (g_9 != dmat3x4(44.0LF, 45.0LF, 46.0LF, 47.0LF, 48.0LF, 49.0LF, 50.0LF, 51.0LF, 52.0LF, " 549148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "53.0LF, 54.0LF, 55.0LF)) g_result = 0;" NL NL 549248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " if (g_10 != dmat4x2(56.0, 57.0, 58.0, 59.0, 60.0, 61.0, 62.0, 63.0)) g_result = 0;" NL 549348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " if (g_11 != dmat4x3(63.0, 64.0, 65.0, 66.0, 67.0, 68.0, 69.0, 70.0, 71.0, 27.0, 73, 74.0)) g_result = " 549448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "0;" NL " if (g_12 != dmat4(75.0, 76.0, 77.0, 78.0, 79.0, 80.0, 81.0, 82.0, 83.0, 84.0, 85.0, 86.0, 87.0, " 549548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "88.0, 89.0, 90.0)) g_result = 0;" NL "}"; 549648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_program = CreateComputeProgram(glsl_cs); 549748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glLinkProgram(m_program); 549848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!CheckProgram(m_program)) 549948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 550048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 550148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGenBuffers(1, &m_storage_buffer); 550248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* create buffer */ 550348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 550448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const int data = 123; 550548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_storage_buffer); 550648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), &data, GL_STATIC_DRAW); 550748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 550848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 550948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glProgramUniform1d(m_program, glGetUniformLocation(m_program, "g_0"), 1.0); 551048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glProgramUniform2d(m_program, glGetUniformLocation(m_program, "g_1"), 2.0, 3.0); 551148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glProgramUniform3d(m_program, glGetUniformLocation(m_program, "g_2"), 4.0, 5.0, 6.0); 551248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glProgramUniform4d(m_program, glGetUniformLocation(m_program, "g_3"), 7.0, 8.0, 9.0, 10.0); 551348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 551448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* mat2 */ 551548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 551648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLdouble value[4] = { 11.0, 12.0, 13.0, 14.0 }; 551748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glProgramUniformMatrix2dv(m_program, glGetUniformLocation(m_program, "g_4"), 1, GL_FALSE, value); 551848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 551948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* mat2x3 */ 552048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 552148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLdouble value[6] = { 15.0, 16.0, 17.0, 18.0, 19.0, 20.0 }; 552248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glProgramUniformMatrix2x3dv(m_program, glGetUniformLocation(m_program, "g_5"), 1, GL_FALSE, value); 552348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 552448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* mat2x4 */ 552548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 552648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLdouble value[8] = { 21.0, 22.0, 23.0, 24.0, 25.0, 26.0, 27.0, 28.0 }; 552748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glProgramUniformMatrix2x4dv(m_program, glGetUniformLocation(m_program, "g_6"), 1, GL_FALSE, value); 552848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 552948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 553048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* mat3x2 */ 553148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 553248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLdouble value[6] = { 29.0, 30.0, 31.0, 32.0, 33.0, 34.0 }; 553348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glProgramUniformMatrix3x2dv(m_program, glGetUniformLocation(m_program, "g_7"), 1, GL_FALSE, value); 553448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 553548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* mat3 */ 553648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 553748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLdouble value[9] = { 35.0, 36.0, 37.0, 38.0, 39.0, 40.0, 41.0, 42.0, 43.0 }; 553848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glProgramUniformMatrix3dv(m_program, glGetUniformLocation(m_program, "g_8"), 1, GL_FALSE, value); 553948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 554048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* mat3x4 */ 554148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 554248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLdouble value[12] = { 44.0, 45.0, 46.0, 47.0, 48.0, 49.0, 50.0, 51.0, 52.0, 53.0, 54.0, 55.0 }; 554348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glProgramUniformMatrix3x4dv(m_program, glGetUniformLocation(m_program, "g_9"), 1, GL_FALSE, value); 554448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 554548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 554648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* mat4x2 */ 554748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 554848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLdouble value[8] = { 56.0, 57.0, 58.0, 59.0, 60.0, 61.0, 62.0, 63.0 }; 554948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glProgramUniformMatrix4x2dv(m_program, glGetUniformLocation(m_program, "g_10"), 1, GL_FALSE, value); 555048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 555148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* mat4x3 */ 555248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 555348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLdouble value[12] = { 63.0, 64.0, 65.0, 66.0, 67.0, 68.0, 69.0, 70.0, 71.0, 27.0, 73, 74.0 }; 555448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glProgramUniformMatrix4x3dv(m_program, glGetUniformLocation(m_program, "g_11"), 1, GL_FALSE, value); 555548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 555648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* mat4 */ 555748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 555848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLdouble value[16] = { 75.0, 76.0, 77.0, 78.0, 79.0, 80.0, 81.0, 82.0, 555948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 83.0, 84.0, 85.0, 86.0, 87.0, 88.0, 89.0, 90.0 }; 556048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glProgramUniformMatrix4dv(m_program, glGetUniformLocation(m_program, "g_12"), 1, GL_FALSE, value); 556148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 556248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 556348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUseProgram(m_program); 556448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDispatchCompute(1, 1, 1); 556548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT); 556648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 556748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* validate */ 556848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 556948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos int data; 557048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, sizeof(data), &data); 557148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (data != 1) 557248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 5573910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() 5574910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << tcu::TestLog::Message << "Data is " << data << " should be 1." << tcu::TestLog::EndMessage; 557548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 557648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 557748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 557848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 557948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos // re-link program (all uniforms will be set to zero) 558048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glLinkProgram(m_program); 558148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 558248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* clear buffer */ 558348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 558448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const int data = 123; 558548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, sizeof(data), &data); 558648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 558748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 558848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUniform1d(glGetUniformLocation(m_program, "g_0"), 1.0); 558948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUniform2d(glGetUniformLocation(m_program, "g_1"), 2.0, 3.0); 559048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUniform3d(glGetUniformLocation(m_program, "g_2"), 4.0, 5.0, 6.0); 559148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUniform4d(glGetUniformLocation(m_program, "g_3"), 7.0, 8.0, 9.0, 10.0); 559248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 559348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* mat2 */ 559448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 559548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLdouble value[4] = { 11.0, 12.0, 13.0, 14.0 }; 559648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUniformMatrix2dv(glGetUniformLocation(m_program, "g_4"), 1, GL_FALSE, value); 559748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 559848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* mat2x3 */ 559948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 560048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLdouble value[6] = { 15.0, 16.0, 17.0, 18.0, 19.0, 20.0 }; 560148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUniformMatrix2x3dv(glGetUniformLocation(m_program, "g_5"), 1, GL_FALSE, value); 560248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 560348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* mat2x4 */ 560448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 560548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLdouble value[8] = { 21.0, 22.0, 23.0, 24.0, 25.0, 26.0, 27.0, 28.0 }; 560648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUniformMatrix2x4dv(glGetUniformLocation(m_program, "g_6"), 1, GL_FALSE, value); 560748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 560848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 560948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* mat3x2 */ 561048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 561148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLdouble value[6] = { 29.0, 30.0, 31.0, 32.0, 33.0, 34.0 }; 561248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUniformMatrix3x2dv(glGetUniformLocation(m_program, "g_7"), 1, GL_FALSE, value); 561348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 561448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* mat3 */ 561548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 561648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLdouble value[9] = { 35.0, 36.0, 37.0, 38.0, 39.0, 40.0, 41.0, 42.0, 43.0 }; 561748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUniformMatrix3dv(glGetUniformLocation(m_program, "g_8"), 1, GL_FALSE, value); 561848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 561948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* mat3x4 */ 562048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 562148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLdouble value[12] = { 44.0, 45.0, 46.0, 47.0, 48.0, 49.0, 50.0, 51.0, 52.0, 53.0, 54.0, 55.0 }; 562248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUniformMatrix3x4dv(glGetUniformLocation(m_program, "g_9"), 1, GL_FALSE, value); 562348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 562448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 562548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* mat4x2 */ 562648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 562748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLdouble value[8] = { 56.0, 57.0, 58.0, 59.0, 60.0, 61.0, 62.0, 63.0 }; 562848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUniformMatrix4x2dv(glGetUniformLocation(m_program, "g_10"), 1, GL_FALSE, value); 562948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 563048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* mat4x3 */ 563148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 563248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLdouble value[12] = { 63.0, 64.0, 65.0, 66.0, 67.0, 68.0, 69.0, 70.0, 71.0, 27.0, 73, 74.0 }; 563348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUniformMatrix4x3dv(glGetUniformLocation(m_program, "g_11"), 1, GL_FALSE, value); 563448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 563548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* mat4 */ 563648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 563748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLdouble value[16] = { 75.0, 76.0, 77.0, 78.0, 79.0, 80.0, 81.0, 82.0, 563848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 83.0, 84.0, 85.0, 86.0, 87.0, 88.0, 89.0, 90.0 }; 563948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUniformMatrix4dv(glGetUniformLocation(m_program, "g_12"), 1, GL_FALSE, value); 564048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 564148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 564248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDispatchCompute(1, 1, 1); 564348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT); 564448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 564548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* validate */ 564648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 564748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos int data; 564848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, sizeof(data), &data); 564948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (data != 1) 565048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 5651910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() 5652910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << tcu::TestLog::Message << "Data is " << data << " should be 1." << tcu::TestLog::EndMessage; 565348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 565448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 565548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 565648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 565748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 565848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 565948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Cleanup() 566048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 566148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUseProgram(0); 566248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteProgram(m_program); 566348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteBuffers(1, &m_storage_buffer); 566448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 566548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 566648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}; 566748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 566848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosclass AdvancedFP64Case3 : public ComputeShaderBase 566948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 567048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Title() 567148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 567248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "FP64 support - subroutines"; 567348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 567448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Purpose() 567548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 567648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "Verify that subroutines that performs double precision computation works as expected in the CS."; 567748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 567848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Method() 567948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 568048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL 568148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "Create and dispatch CS that uses double precision math functions in subroutines to compute output values."; 568248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 568348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string PassCriteria() 568448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 568548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "Everything works as expected."; 568648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 568748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 568848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_program; 568948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_storage_buffer; 569048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 569148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Setup() 569248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 569348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_program = 0; 569448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_storage_buffer = 0; 569548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 569648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 569748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Run() 569848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 569948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* const glsl_cs = 570048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos NL "layout(local_size_x = 1) in;" NL "uniform double[4] g_input;" NL "uniform int index;" NL 570148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "layout(std430, binding = 0) buffer Output {" NL " double g_output[4];" NL "};" NL 570248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine double MathFunc(double x);" NL "subroutine uniform MathFunc g_func[4];" NL 570348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine(MathFunc)" NL "double Func0(double x) {" NL " return abs(x);" // abs(-1.0LF) == 1.0LF 570448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos NL "}" NL "subroutine(MathFunc)" NL "double Func1(double x) {" NL 570548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " return round(x);" // round(2.2LF) == 2.0LF 570648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos NL "}" NL "subroutine(MathFunc)" NL "double Func2(double x) {" NL 570748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " return sign(x);" // sign(3.0LF) == 1.0LF 570848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos NL "}" NL "subroutine(MathFunc)" NL "double Func3(double x) {" NL 570948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " return fract(x);" // fract(4.1LF) == 0.1LF 571048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos NL "}" NL "void main() {" NL " int i = index;" NL " g_output[i] = g_func[i](g_input[i]);" NL "}"; 571148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_program = CreateComputeProgram(glsl_cs); 571248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glLinkProgram(m_program); 571348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!CheckProgram(m_program)) 571448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 571548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 571648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGenBuffers(1, &m_storage_buffer); 571748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_storage_buffer); 571848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBufferData(GL_SHADER_STORAGE_BUFFER, 4 * sizeof(double), NULL, GL_STATIC_DRAW); 571948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 572048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLuint index_compute0 = glGetSubroutineIndex(m_program, GL_COMPUTE_SHADER, "Func0"); 572148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLuint index_compute1 = glGetSubroutineIndex(m_program, GL_COMPUTE_SHADER, "Func1"); 572248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLuint index_compute2 = glGetSubroutineIndex(m_program, GL_COMPUTE_SHADER, "Func2"); 572348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLuint index_compute3 = glGetSubroutineIndex(m_program, GL_COMPUTE_SHADER, "Func3"); 572448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLint loc_compute0 = glGetSubroutineUniformLocation(m_program, GL_COMPUTE_SHADER, "g_func[0]"); 572548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLint loc_compute1 = glGetSubroutineUniformLocation(m_program, GL_COMPUTE_SHADER, "g_func[1]"); 572648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLint loc_compute2 = glGetSubroutineUniformLocation(m_program, GL_COMPUTE_SHADER, "g_func[2]"); 572748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLint loc_compute3 = glGetSubroutineUniformLocation(m_program, GL_COMPUTE_SHADER, "g_func[3]"); 572848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 572948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUseProgram(m_program); 573048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 573148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos // setup subroutines 573248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint indices[4]; 573348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos indices[loc_compute0] = index_compute0; 573448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos indices[loc_compute1] = index_compute1; 573548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos indices[loc_compute2] = index_compute2; 573648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos indices[loc_compute3] = index_compute3; 573748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUniformSubroutinesuiv(GL_COMPUTE_SHADER, 4, indices); 573848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 573948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* set uniforms */ 574048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 574148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLdouble data[4] = { -1.0, 2.2, 3.0, 4.1 }; 574248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUniform1dv(glGetUniformLocation(m_program, "g_input"), 4, data); 574348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 574448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUniform1i(glGetUniformLocation(m_program, "index"), 0); 574548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDispatchCompute(1, 1, 1); 574648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUniform1i(glGetUniformLocation(m_program, "index"), 1); 574748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDispatchCompute(1, 1, 1); 574848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUniform1i(glGetUniformLocation(m_program, "index"), 2); 574948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDispatchCompute(1, 1, 1); 575048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUniform1i(glGetUniformLocation(m_program, "index"), 3); 575148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDispatchCompute(1, 1, 1); 575248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT); 575348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 575448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* validate */ 575548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 575648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLdouble expected[4] = { 1.0, 2.0, 1.0, 0.1 }; 575748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLdouble data[4]; 575848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer); 575948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, sizeof(data), &data); 576048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (int i = 0; i < 4; ++i) 576148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 576248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (fabs(data[i] - expected[i]) > g_color_eps.x()) 576348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 5764910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() 5765910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << tcu::TestLog::Message << "Data at index " << i << " is " << data[i] << " should be " 5766910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << expected[i] << "." << tcu::TestLog::EndMessage; 576748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 576848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 576948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 577048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 577148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 577248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 577348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Cleanup() 577448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 577548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUseProgram(0); 577648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteProgram(m_program); 577748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteBuffers(1, &m_storage_buffer); 577848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 577948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 578048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}; 578148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 578248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosclass AdvancedConditionalDispatching : public ComputeShaderBase 578348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 578448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Title() 578548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 578648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "Conditional Dispatching"; 578748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 578848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Purpose() 578948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 579048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "Verify that DispatchCompute and DispatchComputeIndirect commands work as expected inside " 579148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "conditional blocks."; 579248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 579348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Method() 579448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 579548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "1. Render two quads. One will pass depth-test and the second one will not." NL 579648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "2. Use GL_ANY_SAMPLES_PASSED query objects to 'remember' these results." NL 579748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "3. Use DispatchCompute and DispatchComputeIndirect commands inside conditional blocks using both " 579848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "query objects." NL 579948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "4. Verify that DispatchCompute and DispatchComputeIndirect commands are only executed in" NL 580048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " the conditional block that uses query object that has passed depth-test."; 580148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 580248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string PassCriteria() 580348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 580448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "Everything works as expected."; 580548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 580648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 580748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_program_vsfs; 580848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_program_cs; 580948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_vertex_array; 581048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_query[2]; 581148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_storage_buffer; 581248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_dispatch_buffer; 581348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 581448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Setup() 581548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 581648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_program_vsfs = 0; 581748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_program_cs = 0; 581848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_vertex_array = 0; 581948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos memset(m_query, 0, sizeof(m_query)); 582048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_storage_buffer = 0; 582148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_dispatch_buffer = 0; 582248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 582348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 582448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Run() 582548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 582648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* const glsl_vs = NL 582748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "uniform float g_depth;" NL "uniform vec2[3] g_vertex = vec2[3](vec2(-1, -1), vec2(3, -1), vec2(-1, 3));" NL 582848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void main() {" NL " gl_Position = vec4(g_vertex[gl_VertexID], g_depth, 1);" NL "}"; 582948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 583048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* const glsl_fs = 583148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos NL "layout(location = 0) out vec4 g_color;" NL "void main() {" NL " g_color = vec4(0, 1, 0, 1);" NL "}"; 583248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 583348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_program_vsfs = CreateProgram(glsl_vs, glsl_fs); 583448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glLinkProgram(m_program_vsfs); 583548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!CheckProgram(m_program_vsfs)) 583648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 583748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 583848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* const glsl_cs = 583948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos NL "layout(local_size_x = 1) in;" NL "layout(std430) buffer Output {" NL " int g_output;" NL "};" NL 584048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void main() {" NL " atomicAdd(g_output, 1);" NL "}"; 584148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_program_cs = CreateComputeProgram(glsl_cs); 584248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glLinkProgram(m_program_cs); 584348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!CheckProgram(m_program_cs)) 584448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 584548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 584648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* create storage buffer */ 584748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 584848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const int data = 0; 584948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGenBuffers(1, &m_storage_buffer); 585048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_storage_buffer); 585148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), &data, GL_DYNAMIC_COPY); 585248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 585348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* create dispatch buffer */ 585448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 585548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLuint data[3] = { 2, 2, 2 }; 585648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGenBuffers(1, &m_dispatch_buffer); 585748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBuffer(GL_DISPATCH_INDIRECT_BUFFER, m_dispatch_buffer); 585848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBufferData(GL_DISPATCH_INDIRECT_BUFFER, sizeof(data), data, GL_STATIC_DRAW); 585948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 586048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 586148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGenVertexArrays(1, &m_vertex_array); 586248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGenQueries(2, m_query); 586348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 586448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glEnable(GL_DEPTH_TEST); 586548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 586648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 586748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUseProgram(m_program_vsfs); 586848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindVertexArray(m_vertex_array); 586948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 587048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos // this draw call will pass depth test 587148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBeginQuery(GL_ANY_SAMPLES_PASSED, m_query[0]); 587248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUniform1f(glGetUniformLocation(m_program_vsfs, "g_depth"), 0.0f); 587348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDrawArrays(GL_TRIANGLES, 0, 3); 587448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glEndQuery(GL_ANY_SAMPLES_PASSED); 587548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 587648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos // this draw call will NOT pass depth test 587748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBeginQuery(GL_ANY_SAMPLES_PASSED, m_query[1]); 587848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUniform1f(glGetUniformLocation(m_program_vsfs, "g_depth"), 0.5f); 587948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDrawArrays(GL_TRIANGLES, 0, 3); 588048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glEndQuery(GL_ANY_SAMPLES_PASSED); 588148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 588248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDisable(GL_DEPTH_TEST); 588348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 588448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUseProgram(m_program_cs); 588548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 588648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos // these commands should be executed normally 588748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBeginConditionalRender(m_query[0], GL_QUERY_WAIT); 588848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDispatchCompute(2, 2, 2); 588948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT); 589048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDispatchComputeIndirect(0); 589148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glEndConditionalRender(); 589248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 589348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* validate */ 589448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 589548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos int data; 589648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT); 589748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, sizeof(data), &data); 589848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (data != 16) 589948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 5900910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() 5901910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << tcu::TestLog::Message << "Data is " << data << " should be 16." << tcu::TestLog::EndMessage; 590248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 590348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 590448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 590548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 590648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos // these commands should be discarded 590748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBeginConditionalRender(m_query[1], GL_QUERY_WAIT); 590848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDispatchCompute(2, 2, 2); 590948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT); 591048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDispatchComputeIndirect(0); 591148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glEndConditionalRender(); 591248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 591348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* validate */ 591448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 591548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos int data; 591648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT); 591748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, sizeof(data), &data); 591848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (data != 16 && m_context.getRenderContext().getRenderTarget().getDepthBits() != 0) 591948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 5920910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() 5921910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << tcu::TestLog::Message << "Data is " << data << " should be 16." << tcu::TestLog::EndMessage; 592248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 592348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 592448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else if (data != 32 && m_context.getRenderContext().getRenderTarget().getDepthBits() == 0) 592548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 5926910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() 5927910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << tcu::TestLog::Message << "Data is " << data << " should be 32." << tcu::TestLog::EndMessage; 592848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 592948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 593048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 593148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 593248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!ValidateReadBuffer(0, 0, getWindowWidth(), getWindowHeight(), vec4(0, 1, 0, 1))) 593348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 593448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 593548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 593648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 593748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 593848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 593948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Cleanup() 594048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 594148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUseProgram(0); 594248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteProgram(m_program_vsfs); 594348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteProgram(m_program_cs); 594448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteVertexArrays(1, &m_vertex_array); 594548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteQueries(2, m_query); 594648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteBuffers(1, &m_storage_buffer); 594748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteBuffers(1, &m_dispatch_buffer); 594848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 594948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 595048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}; 595148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 595248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosclass NegativeAPINoActiveProgram : public ComputeShaderBase 595348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 595448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Title() 595548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 595648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "API errors - no active program"; 595748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 595848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Purpose() 595948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 596048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "Verify that appropriate errors are generated by the OpenGL API."; 596148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 596248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Method() 596348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 596448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL ""; 596548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 596648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string PassCriteria() 596748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 596848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL ""; 596948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 597048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 597148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_program; 597248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 597348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Setup() 597448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 597548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_program = 0; 597648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 597748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 597848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Run() 597948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 598048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDispatchCompute(1, 2, 3); 598148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (glGetError() != GL_INVALID_OPERATION) 598248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 5983910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() 5984910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << tcu::TestLog::Message << "INVALID_OPERATION is generated by DispatchCompute or\n" 5985910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << "DispatchComputeIndirect if there is no active program for the compute\n" 5986910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << "shader stage." << tcu::TestLog::EndMessage; 598748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 598848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 598948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 599048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* indirect dispatch */ 599148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 599248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint buffer; 599348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLuint num_group[3] = { 3, 2, 1 }; 599448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGenBuffers(1, &buffer); 599548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBuffer(GL_DISPATCH_INDIRECT_BUFFER, buffer); 599648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBufferData(GL_DISPATCH_INDIRECT_BUFFER, sizeof(num_group), num_group, GL_STATIC_DRAW); 599748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDispatchComputeIndirect(0); 599848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteBuffers(1, &buffer); 599948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (glGetError() != GL_INVALID_OPERATION) 600048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 6001910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() 6002910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << tcu::TestLog::Message << "INVALID_OPERATION is generated by DispatchCompute or\n" 6003910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << "DispatchComputeIndirect if there is no active program for the compute\n" 6004910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << "shader stage." << tcu::TestLog::EndMessage; 600548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 600648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 600748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 600848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 600948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* const glsl_vs = 601048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos NL "layout(location = 0) in vec4 g_position;" NL "void main() {" NL " gl_Position = g_position;" NL "}"; 601148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 601248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* const glsl_fs = 601348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos NL "layout(location = 0) out vec4 g_color;" NL "void main() {" NL " g_color = vec4(1);" NL "}"; 601448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 601548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_program = CreateProgram(glsl_vs, glsl_fs); 601648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glLinkProgram(m_program); 601748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!CheckProgram(m_program)) 601848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 601948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 602048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUseProgram(m_program); 602148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 602248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDispatchCompute(1, 2, 3); 602348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (glGetError() != GL_INVALID_OPERATION) 602448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 6025910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() 6026910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << tcu::TestLog::Message << "INVALID_OPERATION is generated by DispatchCompute or\n" 6027910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << "DispatchComputeIndirect if there is no active program for the compute\n" 6028910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << "shader stage." << tcu::TestLog::EndMessage; 602948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 603048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 603148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 603248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* indirect dispatch */ 603348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 603448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint buffer; 603548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLuint num_group[3] = { 3, 2, 1 }; 603648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGenBuffers(1, &buffer); 603748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBuffer(GL_DISPATCH_INDIRECT_BUFFER, buffer); 603848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBufferData(GL_DISPATCH_INDIRECT_BUFFER, sizeof(num_group), num_group, GL_STATIC_DRAW); 603948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDispatchComputeIndirect(0); 604048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteBuffers(1, &buffer); 604148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (glGetError() != GL_INVALID_OPERATION) 604248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 6043910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() 6044910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << tcu::TestLog::Message << "INVALID_OPERATION is generated by DispatchCompute or\n" 6045910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << "DispatchComputeIndirect if there is no active program for the compute\n" 6046910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << "shader stage." << tcu::TestLog::EndMessage; 604748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 604848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 604948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 605048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 605148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 605248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 605348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Cleanup() 605448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 605548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUseProgram(0); 605648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteProgram(m_program); 605748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 605848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 605948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}; 606048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 606148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosclass NegativeAPIWorkGroupCount : public ComputeShaderBase 606248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 606348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Title() 606448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 606548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "API errors - invalid work group count"; 606648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 606748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Purpose() 606848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 606948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "Verify that appropriate errors are generated by the OpenGL API."; 607048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 607148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Method() 607248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 607348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL ""; 607448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 607548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string PassCriteria() 607648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 607748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL ""; 607848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 607948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 608048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_program; 608148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_storage_buffer; 608248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 608348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Setup() 608448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 608548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_program = 0; 608648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_storage_buffer = 0; 608748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 608848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 608948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Run() 609048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 609148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* const glsl_cs = 609248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos NL "layout(local_size_x = 1) in;" NL "layout(std430) buffer Output {" NL " uint g_output[];" NL "};" NL 609348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void main() {" NL 609448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " g_output[gl_GlobalInvocationID.x * gl_GlobalInvocationID.y * gl_GlobalInvocationID.z] = 0;" NL "}"; 609548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_program = CreateComputeProgram(glsl_cs); 609648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glLinkProgram(m_program); 609748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!CheckProgram(m_program)) 609848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 609948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 610048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGenBuffers(1, &m_storage_buffer); 610148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_storage_buffer); 610248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBufferData(GL_SHADER_STORAGE_BUFFER, 100000, NULL, GL_DYNAMIC_DRAW); 610348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 610448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLint x, y, z; 610548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_COUNT, 0, &x); 610648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_COUNT, 1, &y); 610748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_COUNT, 2, &z); 610848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 610948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUseProgram(m_program); 611048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 611148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDispatchCompute(x + 1, 1, 1); 611248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (glGetError() != GL_INVALID_VALUE) 611348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 6114910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() 6115910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << tcu::TestLog::Message << "INVALID_VALUE is generated by DispatchCompute if any of <num_groups_x>,\n" 6116910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << "<num_groups_y> or <num_groups_z> is greater than the value of\n" 6117910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << "MAX_COMPUTE_WORK_GROUP_COUNT for the corresponding dimension." << tcu::TestLog::EndMessage; 611848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 611948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 612048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 612148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDispatchCompute(1, y + 1, 1); 612248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (glGetError() != GL_INVALID_VALUE) 612348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 6124910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() 6125910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << tcu::TestLog::Message << "INVALID_VALUE is generated by DispatchCompute if any of <num_groups_x>,\n" 6126910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << "<num_groups_y> or <num_groups_z> is greater than the value of\n" 6127910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << "MAX_COMPUTE_WORK_GROUP_COUNT for the corresponding dimension." << tcu::TestLog::EndMessage; 612848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 612948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 613048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 613148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDispatchCompute(1, 1, z + 1); 613248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (glGetError() != GL_INVALID_VALUE) 613348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 6134910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() 6135910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << tcu::TestLog::Message << "INVALID_VALUE is generated by DispatchCompute if any of <num_groups_x>,\n" 6136910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << "<num_groups_y> or <num_groups_z> is greater than the value of\n" 6137910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << "MAX_COMPUTE_WORK_GROUP_COUNT for the corresponding dimension." << tcu::TestLog::EndMessage; 613848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 613948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 614048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 614148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 614248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 614348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Cleanup() 614448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 614548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUseProgram(0); 614648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteProgram(m_program); 614748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteBuffers(1, &m_storage_buffer); 614848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 614948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 615048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}; 615148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 615248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosclass NegativeAPIIndirect : public ComputeShaderBase 615348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 615448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Title() 615548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 615648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "API errors - incorrect DispatchComputeIndirect usage"; 615748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 615848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Purpose() 615948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 616048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "Verify that appropriate errors are generated by the OpenGL API."; 616148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 616248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Method() 616348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 616448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL ""; 616548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 616648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string PassCriteria() 616748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 616848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL ""; 616948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 617048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 617148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_program; 617248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_storage_buffer; 617348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_dispatch_buffer; 617448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 617548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Setup() 617648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 617748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_program = 0; 617848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_storage_buffer = 0; 617948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_dispatch_buffer = 0; 618048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 618148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 618248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 618348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Run() 618448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 618548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* const glsl_cs = 618648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos NL "layout(local_size_x = 1) in;" NL "layout(std430) buffer Output {" NL " uint g_output[];" NL "};" NL 618748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void main() {" NL " g_output[gl_GlobalInvocationID.x] = 0;" NL "}"; 618848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_program = CreateComputeProgram(glsl_cs); 618948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glLinkProgram(m_program); 619048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!CheckProgram(m_program)) 619148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 619248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 619348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGenBuffers(1, &m_storage_buffer); 619448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_storage_buffer); 619548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBufferData(GL_SHADER_STORAGE_BUFFER, 100000, NULL, GL_DYNAMIC_DRAW); 619648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 619748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLuint num_groups[6] = { 1, 1, 1, 1, 1, 1 }; 619848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGenBuffers(1, &m_dispatch_buffer); 619948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBuffer(GL_DISPATCH_INDIRECT_BUFFER, m_dispatch_buffer); 620048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBufferData(GL_DISPATCH_INDIRECT_BUFFER, sizeof(num_groups), num_groups, GL_STATIC_COPY); 620148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 620248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUseProgram(m_program); 620348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 620448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDispatchComputeIndirect(-2); 620548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (glGetError() != GL_INVALID_VALUE) 620648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 6207910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() 6208910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << tcu::TestLog::Message << "INVALID_VALUE is generated by DispatchComputeIndirect if <indirect> is\n" 6209910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << "less than zero or not a multiple of four." << tcu::TestLog::EndMessage; 621048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 621148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 621248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 621348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDispatchComputeIndirect(3); 621448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (glGetError() != GL_INVALID_VALUE) 621548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 6216910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() 6217910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << tcu::TestLog::Message << "INVALID_VALUE is generated by DispatchComputeIndirect if <indirect> is\n" 6218910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << "less than zero or not a multiple of four." << tcu::TestLog::EndMessage; 621948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 622048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 622148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 622248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDispatchComputeIndirect(16); 622348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (glGetError() != GL_INVALID_OPERATION) 622448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 6225910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() 6226910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << tcu::TestLog::Message 6227910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << "INVALID_OPERATION is generated by DispatchComputeIndirect if no buffer is\n" 6228910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << "bound to DISPATCH_INDIRECT_BUFFER or if the command would source data\n" 6229910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << "beyond the end of the bound buffer object." << tcu::TestLog::EndMessage; 623048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 623148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 623248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 623348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBuffer(GL_DISPATCH_INDIRECT_BUFFER, 0); 623448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDispatchComputeIndirect(0); 623548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (glGetError() != GL_INVALID_OPERATION) 623648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 6237910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() 6238910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << tcu::TestLog::Message 6239910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << "INVALID_OPERATION is generated by DispatchComputeIndirect if no buffer is\n" 6240910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << "bound to DISPATCH_INDIRECT_BUFFER or if the command would source data\n" 6241910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << "beyond the end of the bound buffer object." << tcu::TestLog::EndMessage; 624248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 624348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 624448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 624548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 624648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 624748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Cleanup() 624848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 624948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUseProgram(0); 625048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteProgram(m_program); 625148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteBuffers(1, &m_storage_buffer); 625248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteBuffers(1, &m_dispatch_buffer); 625348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 625448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 625548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}; 625648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 625748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosclass NegativeAPIProgram : public ComputeShaderBase 625848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 625948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Title() 626048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 626148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "API errors - program state"; 626248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 626348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Purpose() 626448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 626548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "Verify that appropriate errors are generated by the OpenGL API."; 626648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 626748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Method() 626848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 626948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL ""; 627048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 627148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string PassCriteria() 627248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 627348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL ""; 627448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 627548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 627648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_program; 627748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_storage_buffer; 627848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 627948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Setup() 628048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 628148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_program = 0; 628248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_storage_buffer = 0; 628348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 628448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 628548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Run() 628648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 628748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* const glsl_vs = 628848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos NL "layout(location = 0) in vec4 g_position;" NL "void main() {" NL " gl_Position = g_position;" NL "}"; 628948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 629048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* const glsl_fs = 629148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos NL "layout(location = 0) out vec4 g_color;" NL "void main() {" NL " g_color = vec4(1);" NL "}"; 629248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_program = CreateProgram(glsl_vs, glsl_fs); 629348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 629448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLint v[3]; 629548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetProgramiv(m_program, GL_COMPUTE_WORK_GROUP_SIZE, v); 629648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (glGetError() != GL_INVALID_OPERATION) 629748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 6298910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() 6299910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << tcu::TestLog::Message << "INVALID_OPERATION is generated by GetProgramiv if <pname> is\n" 6300910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << "COMPUTE_LOCAL_WORK_SIZE and either the program has not been linked\n" 6301910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << "successfully, or has been linked but contains no compute shaders." << tcu::TestLog::EndMessage; 630248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 630348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 630448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 630548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glLinkProgram(m_program); 630648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!CheckProgram(m_program)) 630748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 630848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 630948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetProgramiv(m_program, GL_COMPUTE_WORK_GROUP_SIZE, v); 631048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (glGetError() != GL_INVALID_OPERATION) 631148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 6312910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() 6313910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << tcu::TestLog::Message << "INVALID_OPERATION is generated by GetProgramiv if <pname> is\n" 6314910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << "COMPUTE_LOCAL_WORK_SIZE and either the program has not been linked\n" 6315910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << "successfully, or has been linked but contains no compute shaders." << tcu::TestLog::EndMessage; 631648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 631748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 631848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteProgram(m_program); 631948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 632048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* const glsl_cs = 632148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "#version 430 core" NL "layout(local_size_x = 1) in;" NL "layout(std430) buffer Output {" NL 632248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " uint g_output[];" NL "};" NL "void main() {" NL " g_output[gl_GlobalInvocationID.x] = 0;" NL "}"; 632348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_program = glCreateProgram(); 632448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 632548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint sh = glCreateShader(GL_COMPUTE_SHADER); 632648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glAttachShader(m_program, sh); 632748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteShader(sh); 632848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glShaderSource(sh, 1, &glsl_cs, NULL); 632948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glCompileShader(sh); 633048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 633148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos sh = glCreateShader(GL_VERTEX_SHADER); 633248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glAttachShader(m_program, sh); 633348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteShader(sh); 633448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glShaderSource(sh, 1, &glsl_vs, NULL); 633548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glCompileShader(sh); 633648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 633748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos sh = glCreateShader(GL_FRAGMENT_SHADER); 633848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glAttachShader(m_program, sh); 633948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteShader(sh); 634048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glShaderSource(sh, 1, &glsl_fs, NULL); 634148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glCompileShader(sh); 634248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 634348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glLinkProgram(m_program); 634448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLint status; 634548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetProgramiv(m_program, GL_LINK_STATUS, &status); 634648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (status == GL_TRUE) 634748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 6348910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() 6349910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << tcu::TestLog::Message << "LinkProgram will fail if <program> contains a combination" 6350910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << " of compute and\n non-compute shaders.\n" 6351910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << tcu::TestLog::EndMessage; 635248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 635348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 635448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 635548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 635648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 635748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Cleanup() 635848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 635948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUseProgram(0); 636048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteProgram(m_program); 636148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteBuffers(1, &m_storage_buffer); 636248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 636348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 636448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}; 636548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 636648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosclass NegativeGLSLCompileTimeErrors : public ComputeShaderBase 636748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 636848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Title() 636948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 637048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "Compile-time errors"; 637148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 637248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Purpose() 637348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 637448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "Verify that appropriate errors are generated by the GLSL compiler."; 637548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 637648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Method() 637748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 637848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL ""; 637948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 638048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string PassCriteria() 638148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 638248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL ""; 638348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 638448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 638548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static std::string Shader1(int x, int y, int z) 638648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 638748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::stringstream ss; 638848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos ss << "#version 430 core" NL "layout(local_size_x = " << x << ", local_size_y = " << y 638948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << ", local_size_z = " << z << ") in;" NL "layout(std430) buffer Output {" NL " uint g_output[];" NL "};" NL 639048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void main() {" NL " g_output[gl_GlobalInvocationID.x] = 0;" NL "}"; 639148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ss.str(); 639248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 639348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Run() 639448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 639548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos // gl_GlobalInvocationID requires "#version 430" or later or GL_ARB_compute_shader 639648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos // extension enabled 639748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!Compile("#version 420 core" NL "layout(local_size_x = 1) in;" NL "layout(std430) buffer Output {" NL 639848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " uint g_output[];" NL "};" NL "void main() {" NL " g_output[gl_GlobalInvocationID.x] = 0;" NL 639948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}")) 640048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 640148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 640248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!Compile("#version 430 core" NL "layout(local_size_x = 1) in;" NL "layout(local_size_x = 2) in;" NL 640348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "layout(std430) buffer Output {" NL " uint g_output[];" NL "};" NL "void main() {" NL 640448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " g_output[gl_GlobalInvocationID.x] = 0;" NL "}")) 640548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 640648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 640748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!Compile("#version 430 core" NL "layout(local_size_x = 1) in;" NL "in uint x;" NL 640848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "layout(std430) buffer Output {" NL " uint g_output[];" NL "};" NL "void main() {" NL 640948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " g_output[gl_GlobalInvocationID.x] = x;" NL "}")) 641048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 641148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 641248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!Compile("#version 430 core" NL "layout(local_size_x = 1) in;" NL "out uint x;" NL 641348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "layout(std430) buffer Output {" NL " uint g_output[];" NL "};" NL "void main() {" NL 641448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " g_output[gl_GlobalInvocationID.x] = 0;" NL " x = 0;" NL "}")) 641548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 641648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 641748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 641848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLint x, y, z; 641948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_SIZE, 0, &x); 642048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_SIZE, 0, &y); 642148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_SIZE, 0, &z); 642248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 642348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!Compile(Shader1(x + 1, 1, 1))) 642448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 642548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!Compile(Shader1(1, y + 1, 1))) 642648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 642748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!Compile(Shader1(1, 1, z + 1))) 642848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 642948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 643048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 643148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 643248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 643348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 643448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos bool Compile(const std::string& source) 643548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 643648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLuint sh = glCreateShader(GL_COMPUTE_SHADER); 643748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 643848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* const src = source.c_str(); 643948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glShaderSource(sh, 1, &src, NULL); 644048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glCompileShader(sh); 644148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 644248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLchar log[1024]; 644348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetShaderInfoLog(sh, sizeof(log), NULL, log); 6444910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() << tcu::TestLog::Message << "Shader Info Log:\n" 6445910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << log << tcu::TestLog::EndMessage; 644648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 644748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLint status; 644848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetShaderiv(sh, GL_COMPILE_STATUS, &status); 644948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteShader(sh); 645048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 645148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (status == GL_TRUE) 645248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 6453910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() 6454910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << tcu::TestLog::Message << "Compilation should fail." << tcu::TestLog::EndMessage; 645548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return false; 645648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 645748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 645848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return true; 645948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 646048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}; 646148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 646248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosclass NegativeGLSLLinkTimeErrors : public ComputeShaderBase 646348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 646448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Title() 646548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 646648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "Link-time errors"; 646748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 646848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Purpose() 646948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 647048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "Verify that appropriate errors are generated by the GLSL linker."; 647148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 647248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Method() 647348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 647448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL ""; 647548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 647648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string PassCriteria() 647748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 647848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL ""; 647948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 648048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 648148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Run() 648248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 648348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos // no layout 648448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!Link("#version 430 core" NL "void Run();" NL "void main() {" NL " Run();" NL "}", 648548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "#version 430 core" NL "layout(std430) buffer Output {" NL " uint g_output[];" NL "};" NL 648648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void Run() {" NL " g_output[gl_GlobalInvocationID.x] = 0;" NL "}")) 648748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 648848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 648948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!Link("#version 430 core" NL "layout(local_size_x = 2) in;" NL "void Run();" NL "void main() {" NL 649048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " Run();" NL "}", 649148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "#version 430 core" NL "layout(local_size_x = 1) in;" NL "layout(std430) buffer Output {" NL 649248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " uint g_output[];" NL "};" NL "void Run() {" NL " g_output[gl_GlobalInvocationID.x] = 0;" NL "}")) 649348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 649448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 649548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 649648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 649748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 649848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos bool Link(const std::string& cs0, const std::string& cs1) 649948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 650048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLuint p = glCreateProgram(); 650148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 650248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* shader 0 */ 650348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 650448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint sh = glCreateShader(GL_COMPUTE_SHADER); 650548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glAttachShader(p, sh); 650648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteShader(sh); 650748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* const src = cs0.c_str(); 650848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glShaderSource(sh, 1, &src, NULL); 650948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glCompileShader(sh); 651048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 651148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLint status; 651248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetShaderiv(sh, GL_COMPILE_STATUS, &status); 651348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (status == GL_FALSE) 651448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 651548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteProgram(p); 6516910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() 6517910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << tcu::TestLog::Message << "CS0 compilation should be ok." << tcu::TestLog::EndMessage; 651848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return false; 651948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 652048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 652148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* shader 1 */ 652248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 652348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint sh = glCreateShader(GL_COMPUTE_SHADER); 652448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glAttachShader(p, sh); 652548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteShader(sh); 652648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* const src = cs1.c_str(); 652748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glShaderSource(sh, 1, &src, NULL); 652848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glCompileShader(sh); 652948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 653048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLint status; 653148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetShaderiv(sh, GL_COMPILE_STATUS, &status); 653248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (status == GL_FALSE) 653348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 653448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteProgram(p); 6535910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() 6536910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << tcu::TestLog::Message << "CS1 compilation should be ok." << tcu::TestLog::EndMessage; 653748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return false; 653848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 653948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 654048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 654148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glLinkProgram(p); 654248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 654348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLchar log[1024]; 654448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetProgramInfoLog(p, sizeof(log), NULL, log); 6545910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() << tcu::TestLog::Message << "Program Info Log:\n" 6546910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << log << tcu::TestLog::EndMessage; 654748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 654848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLint status; 654948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGetProgramiv(p, GL_LINK_STATUS, &status); 655048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteProgram(p); 655148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 655248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (status == GL_TRUE) 655348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 6554910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() 6555910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << tcu::TestLog::Message << "Link operation should fail." << tcu::TestLog::EndMessage; 655648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return false; 655748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 655848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 655948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return true; 656048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 656148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}; 656248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 656348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosclass BasicWorkGroupSizeIsConst : public ComputeShaderBase 656448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 656548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Title() 656648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 656748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "gl_WorkGroupSize is an constant"; 656848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 656948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Purpose() 657048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 657148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL "Verify that gl_WorkGroupSize can be used as an constant expression."; 657248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 657348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string Method() 657448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 657548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL ""; 657648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 657748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual std::string PassCriteria() 657848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 657948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NL ""; 658048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 658148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 658248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_program; 658348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint m_storage_buffer; 658448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 658548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Setup() 658648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 658748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_program = 0; 658848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_storage_buffer = 0; 658948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 659048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 659148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 659248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Run() 659348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 659448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* const glsl_cs = 659548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos NL "layout(local_size_x = 2, local_size_y = 3, local_size_z = 4) in;" NL 659648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "layout(std430, binding = 0) buffer Output {" NL " uint g_buffer[22 + gl_WorkGroupSize.x];" NL "};" NL 659748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "shared uint g_shared[gl_WorkGroupSize.x * gl_WorkGroupSize.y * gl_WorkGroupSize.z];" NL 659848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "uniform uint g_uniform[gl_WorkGroupSize.z + 20] = { " 659948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24 };" NL "void main() {" NL 660048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " g_shared[gl_LocalInvocationIndex] = 1U;" NL " groupMemoryBarrier();" NL " barrier();" NL 660148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " uint sum = 0;" NL 660248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " for (uint i = 0; i < gl_WorkGroupSize.x * gl_WorkGroupSize.y * gl_WorkGroupSize.z; ++i) {" NL 660348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " sum += g_shared[i];" NL " }" NL " sum += g_uniform[gl_LocalInvocationIndex];" NL 660448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " g_buffer[gl_LocalInvocationIndex] = sum;" NL "}"; 660548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_program = CreateComputeProgram(glsl_cs); 660648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glLinkProgram(m_program); 660748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!CheckProgram(m_program)) 660848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return ERROR; 660948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 661048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glGenBuffers(1, &m_storage_buffer); 661148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_storage_buffer); 661248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBufferData(GL_SHADER_STORAGE_BUFFER, 24 * sizeof(GLuint), NULL, GL_STATIC_DRAW); 661348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 661448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUseProgram(m_program); 661548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDispatchCompute(1, 1, 1); 661648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT); 661748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 661848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos long error = NO_ERROR; 661948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint* data; 662048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_storage_buffer); 662148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos data = 662248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static_cast<GLuint*>(glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, sizeof(GLuint) * 24, GL_MAP_READ_BIT)); 662348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLuint i = 0; i < 24; ++i) 662448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 662548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (data[i] != (i + 25)) 662648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 6627910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski m_context.getTestContext().getLog() 6628910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << tcu::TestLog::Message << "Data at index " << i << " is " << data[i] << " should be " << i + 25 6629910dcf5adcc9b50cb1ca75369927bbd44c231c37Piotr Byszewski << "." << tcu::TestLog::EndMessage; 663048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos error = ERROR; 663148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 663248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 663348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUnmapBuffer(GL_SHADER_STORAGE_BUFFER); 663448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0); 663548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return error; 663648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 663748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 663848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos virtual long Cleanup() 663948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 664048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glUseProgram(0); 664148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteProgram(m_program); 664248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glDeleteBuffers(1, &m_storage_buffer); 664348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return NO_ERROR; 664448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 664548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}; 664648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 664748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} // anonymous namespace 664848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 664948087f5f0eb08759ee763f98daf3b34becb74559Pyry HaulosComputeShaderTests::ComputeShaderTests(deqp::Context& context) : TestCaseGroup(context, "compute_shader", "") 665048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 665148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 665248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 665348087f5f0eb08759ee763f98daf3b34becb74559Pyry HaulosComputeShaderTests::~ComputeShaderTests(void) 665448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 665548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 665648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 665748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid ComputeShaderTests::init() 665848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 665948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos using namespace deqp; 666048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos addChild(new TestSubcase(m_context, "simple-compute", TestSubcase::Create<SimpleCompute>)); 666148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos addChild(new TestSubcase(m_context, "one-work-group", TestSubcase::Create<BasicOneWorkGroup>)); 666248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos addChild(new TestSubcase(m_context, "resource-ubo", TestSubcase::Create<BasicResourceUBO>)); 666348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos addChild(new TestSubcase(m_context, "resource-texture", TestSubcase::Create<BasicResourceTexture>)); 666448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos addChild(new TestSubcase(m_context, "resource-image", TestSubcase::Create<BasicResourceImage>)); 666548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos addChild(new TestSubcase(m_context, "resource-atomic-counter", TestSubcase::Create<BasicResourceAtomicCounter>)); 666648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos addChild(new TestSubcase(m_context, "resource-subroutine", TestSubcase::Create<BasicResourceSubroutine>)); 666748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos addChild(new TestSubcase(m_context, "resource-uniform", TestSubcase::Create<BasicResourceUniform>)); 666848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos addChild(new TestSubcase(m_context, "built-in-variables", TestSubcase::Create<BasicBuiltinVariables>)); 666948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos addChild(new TestSubcase(m_context, "max", TestSubcase::Create<BasicMax>)); 667048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos addChild(new TestSubcase(m_context, "work-group-size", TestSubcase::Create<BasicWorkGroupSizeIsConst>)); 667148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos addChild(new TestSubcase(m_context, "build-monolithic", TestSubcase::Create<BasicBuildMonolithic>)); 667248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos addChild(new TestSubcase(m_context, "build-separable", TestSubcase::Create<BasicBuildSeparable>)); 667348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos addChild(new TestSubcase(m_context, "shared-simple", TestSubcase::Create<BasicSharedSimple>)); 667448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos addChild(new TestSubcase(m_context, "shared-struct", TestSubcase::Create<BasicSharedStruct>)); 667548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos addChild(new TestSubcase(m_context, "dispatch-indirect", TestSubcase::Create<BasicDispatchIndirect>)); 667648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos addChild(new TestSubcase(m_context, "sso-compute-pipeline", TestSubcase::Create<BasicSSOComputePipeline>)); 667748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos addChild(new TestSubcase(m_context, "sso-case2", TestSubcase::Create<BasicSSOCase2>)); 667848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos addChild(new TestSubcase(m_context, "sso-case3", TestSubcase::Create<BasicSSOCase3>)); 667948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos addChild(new TestSubcase(m_context, "atomic-case1", TestSubcase::Create<BasicAtomicCase1>)); 668048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos addChild(new TestSubcase(m_context, "atomic-case2", TestSubcase::Create<BasicAtomicCase2>)); 668148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos addChild(new TestSubcase(m_context, "atomic-case3", TestSubcase::Create<BasicAtomicCase3>)); 668248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos addChild(new TestSubcase(m_context, "copy-image", TestSubcase::Create<AdvancedCopyImage>)); 668348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos addChild(new TestSubcase(m_context, "pipeline-pre-vs", TestSubcase::Create<AdvancedPipelinePreVS>)); 668448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos addChild( 668548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos new TestSubcase(m_context, "pipeline-gen-draw-commands", TestSubcase::Create<AdvancedPipelineGenDrawCommands>)); 668648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos addChild(new TestSubcase(m_context, "pipeline-compute-chain", TestSubcase::Create<AdvancedPipelineComputeChain>)); 668748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos addChild(new TestSubcase(m_context, "pipeline-post-fs", TestSubcase::Create<AdvancedPipelinePostFS>)); 668848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos addChild(new TestSubcase(m_context, "pipeline-post-xfb", TestSubcase::Create<AdvancedPipelinePostXFB>)); 668948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos addChild(new TestSubcase(m_context, "shared-indexing", TestSubcase::Create<AdvancedSharedIndexing>)); 669048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos addChild(new TestSubcase(m_context, "shared-max", TestSubcase::Create<AdvancedSharedMax>)); 669148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos addChild(new TestSubcase(m_context, "dynamic-paths", TestSubcase::Create<AdvancedDynamicPaths>)); 669248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos addChild(new TestSubcase(m_context, "resources-max", TestSubcase::Create<AdvancedResourcesMax>)); 669348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos addChild(new TestSubcase(m_context, "fp64-case1", TestSubcase::Create<AdvancedFP64Case1>)); 669448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos addChild(new TestSubcase(m_context, "fp64-case2", TestSubcase::Create<AdvancedFP64Case2>)); 669548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos addChild(new TestSubcase(m_context, "fp64-case3", TestSubcase::Create<AdvancedFP64Case3>)); 669648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos addChild( 669748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos new TestSubcase(m_context, "conditional-dispatching", TestSubcase::Create<AdvancedConditionalDispatching>)); 669848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos addChild(new TestSubcase(m_context, "api-no-active-program", TestSubcase::Create<NegativeAPINoActiveProgram>)); 669948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos addChild(new TestSubcase(m_context, "api-work-group-count", TestSubcase::Create<NegativeAPIWorkGroupCount>)); 670048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos addChild(new TestSubcase(m_context, "api-indirect", TestSubcase::Create<NegativeAPIIndirect>)); 670148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos addChild(new TestSubcase(m_context, "api-program", TestSubcase::Create<NegativeAPIProgram>)); 670248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos addChild( 670348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos new TestSubcase(m_context, "glsl-compile-time-errors", TestSubcase::Create<NegativeGLSLCompileTimeErrors>)); 670448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos addChild(new TestSubcase(m_context, "glsl-link-time-errors", TestSubcase::Create<NegativeGLSLLinkTimeErrors>)); 670548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 670648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} // gl4cts namespace 6707