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/*! 2548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * \file esextcGPUShader5AtomicCountersArrayIndexing.cpp 2648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * \brief GPUShader5 Atomic Counters Array Indexing (Test 3) 2784322c9402f810da3cd80b52e9f9ef72150a9004Alexander Galazin */ /*-------------------------------------------------------------------*/ 2848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 2948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#include "esextcGPUShader5AtomicCountersArrayIndexing.hpp" 3048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#include "gluContextInfo.hpp" 3148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#include "gluDefs.hpp" 3248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#include "glwEnums.hpp" 3348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#include "glwFunctions.hpp" 3448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#include "tcuTestLog.hpp" 3548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#include <cstring> 3648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 3748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosnamespace glcts 3848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 3948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosconst glw::GLuint GPUShader5AtomicCountersArrayIndexing::m_atomic_counters_array_size = 4; 4048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 4148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/* Compute Shader code */ 4248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosconst char* GPUShader5AtomicCountersArrayIndexing::m_compute_shader_code = 4348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "${VERSION}\n" 4448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 4548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "${GPU_SHADER5_REQUIRE}\n" 4648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 4748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "layout (local_size_x = 2, local_size_y = 2) in;\n" 4848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "layout (binding = 0, offset = 0) uniform atomic_uint counters[4];\n" 4948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 5048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void main(void)\n" 5148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 5248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " for (uint index = 0u; index <= 3u; ++index)\n" 5348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " {\n" 5448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " for (uint iteration = 0u; iteration <= gl_LocalInvocationID.x * 2u + gl_LocalInvocationID.y; " 5548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "++iteration)\n" 5648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " {\n" 5748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " atomicCounterIncrement( counters[index] );\n" 5848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " }\n" 5948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " }\n" 6048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n"; 6148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 6248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Constructor 6348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 6448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param context Test context 6548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param name Test case's name 6648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param description Test case's description 6748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 6848087f5f0eb08759ee763f98daf3b34becb74559Pyry HaulosGPUShader5AtomicCountersArrayIndexing::GPUShader5AtomicCountersArrayIndexing(Context& context, 6948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const ExtParameters& extParams, 7048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* name, const char* description) 7148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos : TestCaseBase(context, extParams, name, description), m_buffer_id(0), m_compute_shader_id(0), m_program_id(0) 7248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 7348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Nothing to be done here */ 7448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 7548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 7648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Initializes GLES objects used during the test. 7748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 7848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos */ 7948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid GPUShader5AtomicCountersArrayIndexing::initTest(void) 8048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 8148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 8248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 8348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Check if gpu_shader5 extension is supported */ 8448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!m_is_gpu_shader5_supported) 8548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 8648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos throw tcu::NotSupportedError(GPU_SHADER5_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__); 8748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 8848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 8948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Create program object from the supplied compute shader code */ 9048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_program_id = gl.createProgram(); 9148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "Creating program object failed"); 9248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 9348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_compute_shader_id = gl.createShader(GL_COMPUTE_SHADER); 9448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "Creating compute shader object failed"); 9548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 9648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!buildProgram(m_program_id, m_compute_shader_id, 1, &m_compute_shader_code)) 9748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 9848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos TCU_FAIL("Could not create program object!"); 9948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 10048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 10148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glw::GLuint bufferData[m_atomic_counters_array_size]; 10248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (glw::GLuint index = 0; index < m_atomic_counters_array_size; ++index) 10348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 10448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos bufferData[index] = index; 10548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 10648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 10748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.genBuffers(1, &m_buffer_id); 10848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.bindBuffer(GL_ATOMIC_COUNTER_BUFFER, m_buffer_id); 10948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.bufferData(GL_ATOMIC_COUNTER_BUFFER, m_atomic_counters_array_size * sizeof(glw::GLuint), bufferData, 11048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GL_DYNAMIC_COPY); 11148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.bindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0, m_buffer_id); 11248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 11348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "Could not setup buffer object!"); 11448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 11548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 11648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Executes the test. 11748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 11848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise. 11948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 12048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * Note the function throws exception should an error occur! 12148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 12248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again. 12348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 12448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulostcu::TestNode::IterateResult GPUShader5AtomicCountersArrayIndexing::iterate(void) 12548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 12648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos initTest(); 12748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 12848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 12948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 13048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Do the computations */ 13148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.useProgram(m_program_id); 13248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "Could not use program object!"); 13348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 13448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.dispatchCompute(10, /* num_groups_x */ 13548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 10, /* num_groups_y */ 13648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1); /* num_groups_z */ 13748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to dispatch compute operation!"); 13848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 13948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Map the buffer object storage into user space */ 14048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glw::GLuint* bufferData = 14148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos (glw::GLuint*)gl.mapBufferRange(GL_ATOMIC_COUNTER_BUFFER, 0, /* offset */ 14248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_atomic_counters_array_size * sizeof(glw::GLuint), GL_MAP_READ_BIT); 14348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to map buffer range to client space!"); 14448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 14548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Compare the result values with reference value */ 14648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::GLuint expectedResult = 1000; 14748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 14848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (expectedResult != bufferData[0] || expectedResult + 1 != bufferData[1] || expectedResult + 2 != bufferData[2] || 14948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos expectedResult + 3 != bufferData[3]) 15048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 15148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.getLog() << tcu::TestLog::Message << "Invalid data rendered. Expected Data" 15248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << " (" << expectedResult << ", " << expectedResult << ", " << expectedResult << ", " 15348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << expectedResult << ") Result Data" 15448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << " (" << bufferData[0] << " ," << bufferData[1] << " ," << bufferData[2] << " ," 15548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << bufferData[3] << ")" << tcu::TestLog::EndMessage; 15648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 15748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.unmapBuffer(GL_ATOMIC_COUNTER_BUFFER); 15848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to unmap buffer!"); 15948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 16048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 16148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return STOP; 16248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 16348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 16448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.unmapBuffer(GL_ATOMIC_COUNTER_BUFFER); 16548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to unmap buffer!"); 16648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 16748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 16848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return STOP; 16948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 17048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 17148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Deinitializes GLES objects created during the test. 17248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 17348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos */ 17448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid GPUShader5AtomicCountersArrayIndexing::deinit(void) 17548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 17648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 17748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 17848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Reset OpenGL ES state */ 17948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.useProgram(0); 18048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.bindBuffer(GL_ATOMIC_COUNTER_BUFFER, 0); 18148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 18248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_program_id != 0) 18348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 18448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteProgram(m_program_id); 18548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_program_id = 0; 18648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 18748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 18848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_compute_shader_id != 0) 18948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 19048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteShader(m_compute_shader_id); 19148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_compute_shader_id = 0; 19248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 19348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 19448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_buffer_id != 0) 19548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 19648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteBuffers(1, &m_buffer_id); 19748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_buffer_id = 0; 19848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 19948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 20048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Release base class */ 20148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos TestCaseBase::deinit(); 20248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 20348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 20448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} // namespace glcts 205