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 gl4cShaderSubroutineTests.cpp 2648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * \brief Implements conformance tests for "Shader Subroutine" functionality. 2784322c9402f810da3cd80b52e9f9ef72150a9004Alexander Galazin */ /*-------------------------------------------------------------------*/ 2848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 2948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#include "gl4cShaderSubroutineTests.hpp" 3048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#include "gluContextInfo.hpp" 3148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#include "glwEnums.hpp" 3248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#include "glwFunctions.hpp" 3348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#include "tcuMatrix.hpp" 3448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#include <cmath> 3548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#include <cstring> 3648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#include <deMath.h> 3748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 3848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosusing namespace glw; 3948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 4048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosnamespace gl4cts 4148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 4248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosnamespace ShaderSubroutine 4348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 4448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Constructor. 4548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 4648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param context CTS context. 4748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 4848087f5f0eb08759ee763f98daf3b34becb74559Pyry HaulosUtils::buffer::buffer(deqp::Context& context) : m_id(0), m_context(context) 4948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 5048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 5148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 5248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Destructor 5348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 5448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 5548087f5f0eb08759ee763f98daf3b34becb74559Pyry HaulosUtils::buffer::~buffer() 5648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 5748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (0 != m_id) 5848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 5948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 6048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 6148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteBuffers(1, &m_id); 6248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_id = 0; 6348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 6448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 6548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 6648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Execute BindBufferRange 6748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 6848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param target <target> parameter 6948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param index <index> parameter 7048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param offset <offset> parameter 7148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param size <size> parameter 7248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 7348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid Utils::buffer::bindRange(glw::GLenum target, glw::GLuint index, glw::GLintptr offset, glw::GLsizeiptr size) 7448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 7548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 7648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 7748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.bindBufferRange(target, index, m_id, offset, size); 7848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "BindBufferRange"); 7948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 8048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 8148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Execute GenBuffer 8248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 8348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 8448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid Utils::buffer::generate() 8548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 8648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 8748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 8848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.genBuffers(1, &m_id); 8948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "GenBuffers"); 9048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 9148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 9248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Execute BufferData 9348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 9448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param target <target> parameter 9548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param size <size> parameter 9648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param data <data> parameter 9748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param usage <usage> parameter 9848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 9948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid Utils::buffer::update(glw::GLenum target, glw::GLsizeiptr size, glw::GLvoid* data, glw::GLenum usage) 10048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 10148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 10248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 10348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.bindBuffer(target, m_id); 10448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "bindBuffer"); 10548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 10648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.bufferData(target, size, data, usage); 10748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "bufferData"); 10848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 10948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 11048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Constructor 11148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 11248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param context CTS context 11348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 11448087f5f0eb08759ee763f98daf3b34becb74559Pyry HaulosUtils::framebuffer::framebuffer(deqp::Context& context) : m_id(0), m_context(context) 11548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 11648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Nothing to be done here */ 11748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 11848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 11948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Destructor 12048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 12148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 12248087f5f0eb08759ee763f98daf3b34becb74559Pyry HaulosUtils::framebuffer::~framebuffer() 12348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 12448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (0 != m_id) 12548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 12648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 12748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 12848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteFramebuffers(1, &m_id); 12948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_id = 0; 13048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 13148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 13248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 13348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Attach texture to specified attachment 13448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 13548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param attachment Attachment 13648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param texture_id Texture id 13748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param width Texture width 13848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param height Texture height 13948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 14048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid Utils::framebuffer::attachTexture(glw::GLenum attachment, glw::GLuint texture_id, glw::GLuint width, 14148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glw::GLuint height) 14248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 14348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 14448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 14548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos bind(); 14648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 14748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.bindTexture(GL_TEXTURE_2D, texture_id); 14848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture"); 14948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 15048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.framebufferTexture2D(GL_DRAW_FRAMEBUFFER, attachment, GL_TEXTURE_2D, texture_id, 0 /* level */); 15148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 15248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "FramebufferTexture2D"); 15348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 15448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.viewport(0 /* x */, 0 /* y */, width, height); 15548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "Viewport"); 15648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 15748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 15848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Binds framebuffer to DRAW_FRAMEBUFFER 15948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 16048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 16148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid Utils::framebuffer::bind() 16248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 16348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 16448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 16548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, m_id); 16648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "BindFramebuffer"); 16748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 16848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 16948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Clear framebuffer 17048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 17148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param mask <mask> parameter of glClear. Decides which shall be cleared 17248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 17348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid Utils::framebuffer::clear(glw::GLenum mask) 17448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 17548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 17648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 17748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.clear(mask); 17848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "Clear"); 17948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 18048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 18148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Specifie clear color 18248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 18348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param red Red channel 18448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param green Green channel 18548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param blue Blue channel 18648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param alpha Alpha channel 18748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 18848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid Utils::framebuffer::clearColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) 18948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 19048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 19148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 19248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.clearColor(red, green, blue, alpha); 19348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "ClearColor"); 19448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 19548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 19648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Generate framebuffer 19748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 19848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 19948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid Utils::framebuffer::generate() 20048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 20148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 20248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 20348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.genFramebuffers(1, &m_id); 20448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "GenFramebuffers"); 20548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 20648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 20748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosconst glw::GLenum Utils::program::ARB_COMPUTE_SHADER = 0x91B9; 20848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 20948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Constructor. 21048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 21148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param context CTS context. 21248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 21348087f5f0eb08759ee763f98daf3b34becb74559Pyry HaulosUtils::program::program(deqp::Context& context) 21448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos : m_compute_shader_id(0) 21548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_fragment_shader_id(0) 21648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_geometry_shader_id(0) 21748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_program_object_id(0) 21848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_tesselation_control_shader_id(0) 21948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_tesselation_evaluation_shader_id(0) 22048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_vertex_shader_id(0) 22148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_context(context) 22248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 22348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Nothing to be done here */ 22448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 22548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 22648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Destructor 22748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 22848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 22948087f5f0eb08759ee763f98daf3b34becb74559Pyry HaulosUtils::program::~program() 23048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 23148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos remove(); 23248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 23348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 23448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Build program 23548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 23648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param compute_shader_code Compute shader source code 23748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param fragment_shader_code Fragment shader source code 23848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param geometry_shader_code Geometry shader source code 23948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param tesselation_control_shader_code Tesselation control shader source code 24048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param tesselation_evaluation_shader_code Tesselation evaluation shader source code 24148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param vertex_shader_code Vertex shader source code 24248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param varying_names Array of strings containing names of varyings to be captured with transfrom feedback 24348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param n_varying_names Number of varyings to be captured with transfrom feedback 24448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param is_separable Selects if monolithis or separable program should be built. Defaults to false 24548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 24648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid Utils::program::build(const glw::GLchar* compute_shader_code, const glw::GLchar* fragment_shader_code, 24748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::GLchar* geometry_shader_code, const glw::GLchar* tesselation_control_shader_code, 24848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::GLchar* tesselation_evaluation_shader_code, const glw::GLchar* vertex_shader_code, 24948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::GLchar* const* varying_names, glw::GLuint n_varying_names, bool is_separable) 25048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 25148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* GL entry points */ 25248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 25348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 25448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Create shader objects and compile */ 25548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (0 != compute_shader_code) 25648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 25748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_compute_shader_id = gl.createShader(ARB_COMPUTE_SHADER); 25848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "CreateShader"); 25948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 26048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos compile(m_compute_shader_id, compute_shader_code); 26148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 26248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 26348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (0 != fragment_shader_code) 26448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 26548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_fragment_shader_id = gl.createShader(GL_FRAGMENT_SHADER); 26648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "CreateShader"); 26748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 26848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos compile(m_fragment_shader_id, fragment_shader_code); 26948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 27048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 27148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (0 != geometry_shader_code) 27248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 27348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_geometry_shader_id = gl.createShader(GL_GEOMETRY_SHADER); 27448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "CreateShader"); 27548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 27648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos compile(m_geometry_shader_id, geometry_shader_code); 27748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 27848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 27948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (0 != tesselation_control_shader_code) 28048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 28148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_tesselation_control_shader_id = gl.createShader(GL_TESS_CONTROL_SHADER); 28248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "CreateShader"); 28348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 28448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos compile(m_tesselation_control_shader_id, tesselation_control_shader_code); 28548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 28648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 28748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (0 != tesselation_evaluation_shader_code) 28848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 28948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_tesselation_evaluation_shader_id = gl.createShader(GL_TESS_EVALUATION_SHADER); 29048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "CreateShader"); 29148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 29248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos compile(m_tesselation_evaluation_shader_id, tesselation_evaluation_shader_code); 29348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 29448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 29548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (0 != vertex_shader_code) 29648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 29748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_vertex_shader_id = gl.createShader(GL_VERTEX_SHADER); 29848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "CreateShader"); 29948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 30048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos compile(m_vertex_shader_id, vertex_shader_code); 30148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 30248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 30348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Create program object */ 30448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_program_object_id = gl.createProgram(); 30548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "CreateProgram"); 30648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 30748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Set up captyured varyings' names */ 30848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (0 != n_varying_names) 30948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 31048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.transformFeedbackVaryings(m_program_object_id, n_varying_names, varying_names, GL_INTERLEAVED_ATTRIBS); 31148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "TransformFeedbackVaryings"); 31248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 31348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 31448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Set separable parameter */ 31548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (true == is_separable) 31648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 31748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.programParameteri(m_program_object_id, GL_PROGRAM_SEPARABLE, GL_TRUE); 31848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "ProgramParameteri"); 31948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 32048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 32148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Link program */ 32248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos link(); 32348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 32448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 32548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Compile shader 32648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 32748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param shader_id Shader object id 32848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param shader_code Shader source code 32948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 33048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid Utils::program::compile(glw::GLuint shader_id, const glw::GLchar* shader_code) const 33148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 33248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* GL entry points */ 33348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 33448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 33548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Compilation status */ 33648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glw::GLint status = GL_FALSE; 33748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 33848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Set source code */ 33948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.shaderSource(shader_id, 1 /* count */, &shader_code, 0); 34048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "ShaderSource"); 34148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 34248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Compile */ 34348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.compileShader(shader_id); 34448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "CompileShader"); 34548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 34648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Get compilation status */ 34748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getShaderiv(shader_id, GL_COMPILE_STATUS, &status); 34848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderiv"); 34948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 35048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Log compilation error */ 35148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (GL_TRUE != status) 35248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 35348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glw::GLint length = 0; 35448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::vector<glw::GLchar> message; 35548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 35648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Error log length */ 35748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getShaderiv(shader_id, GL_INFO_LOG_LENGTH, &length); 35848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderiv"); 35948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 36048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Prepare storage */ 36148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos message.resize(length); 36248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 36348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Get error log */ 36448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getShaderInfoLog(shader_id, length, 0, &message[0]); 36548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderInfoLog"); 36648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 36748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Log */ 36848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_context.getTestContext().getLog() << tcu::TestLog::Message << "Failed to compile shader:\n" 36948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << &message[0] << "\nShader source\n" 37048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << shader_code << tcu::TestLog::EndMessage; 37148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 37248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos TCU_FAIL("Failed to compile shader"); 37348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 37448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 37548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 37648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Checks whether the tested driver supports GL_ARB_get_program_binary 37748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 37848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return true if the extension is supported and, also, at least one binary format. 37948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 38048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosbool Utils::program::isProgramBinarySupported() const 38148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 38248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glw::GLint n_program_binary_formats = 0; 38348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 38448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 38548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 38648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_context.getContextInfo().isExtensionSupported("GL_ARB_get_program_binary")) 38748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 38848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getIntegerv(GL_NUM_PROGRAM_BINARY_FORMATS, &n_program_binary_formats); 38948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() call failed."); 39048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 39148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 39248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return n_program_binary_formats > 0; 39348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 39448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 39548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Create program from provided binary 39648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 39748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param binary Buffer with binary form of program 39848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param binary_format Format of <binary> data 39948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 40048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid Utils::program::createFromBinary(const std::vector<GLubyte>& binary, GLenum binary_format) 40148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 40248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* GL entry points */ 40348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 40448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 40548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Create program object */ 40648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_program_object_id = gl.createProgram(); 40748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "CreateProgram"); 40848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 40948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.programBinary(m_program_object_id, binary_format, &binary[0], (GLsizei)binary.size()); 41048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "ProgramBinary"); 41148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 41248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 41348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Get binary form of program 41448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 41548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param binary Buffer for binary data 41648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param binary_format Format of binary data 41748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 41848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid Utils::program::getBinary(std::vector<GLubyte>& binary, GLenum& binary_format) const 41948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 42048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* GL entry points */ 42148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 42248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 42348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Get binary size */ 42448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLint length = 0; 42548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getProgramiv(m_program_object_id, GL_PROGRAM_BINARY_LENGTH, &length); 42648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramiv"); 42748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 42848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Allocate storage */ 42948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos binary.resize(length); 43048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 43148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Get binary */ 43248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getProgramBinary(m_program_object_id, (GLsizei)binary.size(), &length, &binary_format, &binary[0]); 43348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramBinary"); 43448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 43548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 43648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Get subroutine index 43748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 43848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param subroutine_name Subroutine name 43948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 44048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return Index of subroutine 44148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 44248087f5f0eb08759ee763f98daf3b34becb74559Pyry HaulosGLuint Utils::program::getSubroutineIndex(const glw::GLchar* subroutine_name, glw::GLenum shader_stage) const 44348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 44448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 44548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint index = -1; 44648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 44748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos index = gl.getSubroutineIndex(m_program_object_id, shader_stage, subroutine_name); 44848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "GetSubroutineIndex"); 44948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 45048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (GL_INVALID_INDEX == index) 45148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 45248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_context.getTestContext().getLog() << tcu::TestLog::Message << "Subroutine: " << subroutine_name 45348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << " is not available" << tcu::TestLog::EndMessage; 45448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 45548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos TCU_FAIL("Subroutine is not available"); 45648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 45748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 45848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return index; 45948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 46048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 46148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Get subroutine uniform location 46248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 46348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param uniform_name Subroutine uniform name 46448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 46548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return Location of subroutine uniform 46648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 46748087f5f0eb08759ee763f98daf3b34becb74559Pyry HaulosGLint Utils::program::getSubroutineUniformLocation(const glw::GLchar* uniform_name, glw::GLenum shader_stage) const 46848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 46948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 47048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLint location = -1; 47148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 47248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos location = gl.getSubroutineUniformLocation(m_program_object_id, shader_stage, uniform_name); 47348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "GetSubroutineUniformLocation"); 47448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 47548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (-1 == location) 47648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 47748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_context.getTestContext().getLog() << tcu::TestLog::Message << "Subroutine uniform: " << uniform_name 47848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << " is not available" << tcu::TestLog::EndMessage; 47948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 48048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos TCU_FAIL("Subroutine uniform is not available"); 48148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 48248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 48348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return location; 48448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 48548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 48648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Get uniform location 48748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 48848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param uniform_name Subroutine uniform name 48948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 49048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return Location of uniform 49148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 49248087f5f0eb08759ee763f98daf3b34becb74559Pyry HaulosGLint Utils::program::getUniformLocation(const glw::GLchar* uniform_name) const 49348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 49448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 49548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLint location = -1; 49648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 49748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos location = gl.getUniformLocation(m_program_object_id, uniform_name); 49848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "GetUniformLocation"); 49948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 50048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (-1 == location) 50148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 50248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_context.getTestContext().getLog() << tcu::TestLog::Message << "Uniform: " << uniform_name 50348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << " is not available" << tcu::TestLog::EndMessage; 50448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 50548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos TCU_FAIL("Uniform is not available"); 50648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 50748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 50848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return location; 50948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 51048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 51148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Attach shaders and link program 51248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 51348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 51448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid Utils::program::link() const 51548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 51648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* GL entry points */ 51748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 51848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 51948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Link status */ 52048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glw::GLint status = GL_FALSE; 52148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 52248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Attach shaders */ 52348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (0 != m_compute_shader_id) 52448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 52548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.attachShader(m_program_object_id, m_compute_shader_id); 52648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "AttachShader"); 52748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 52848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 52948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (0 != m_fragment_shader_id) 53048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 53148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.attachShader(m_program_object_id, m_fragment_shader_id); 53248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "AttachShader"); 53348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 53448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 53548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (0 != m_geometry_shader_id) 53648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 53748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.attachShader(m_program_object_id, m_geometry_shader_id); 53848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "AttachShader"); 53948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 54048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 54148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (0 != m_tesselation_control_shader_id) 54248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 54348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.attachShader(m_program_object_id, m_tesselation_control_shader_id); 54448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "AttachShader"); 54548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 54648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 54748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (0 != m_tesselation_evaluation_shader_id) 54848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 54948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.attachShader(m_program_object_id, m_tesselation_evaluation_shader_id); 55048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "AttachShader"); 55148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 55248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 55348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (0 != m_vertex_shader_id) 55448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 55548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.attachShader(m_program_object_id, m_vertex_shader_id); 55648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "AttachShader"); 55748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 55848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 55948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Link */ 56048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.linkProgram(m_program_object_id); 56148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "LinkProgram"); 56248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 56348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Get link status */ 56448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getProgramiv(m_program_object_id, GL_LINK_STATUS, &status); 56548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramiv"); 56648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 56748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Log link error */ 56848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (GL_TRUE != status) 56948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 57048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glw::GLint length = 0; 57148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::vector<glw::GLchar> message; 57248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 57348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Get error log length */ 57448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getProgramiv(m_program_object_id, GL_INFO_LOG_LENGTH, &length); 57548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramiv"); 57648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 57748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos message.resize(length); 57848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 57948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Get error log */ 58048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getProgramInfoLog(m_program_object_id, length, 0, &message[0]); 58148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramInfoLog"); 58248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 58348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Log */ 58448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_context.getTestContext().getLog() << tcu::TestLog::Message << "Failed to link program:\n" 58548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << &message[0] << tcu::TestLog::EndMessage; 58648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 58748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos TCU_FAIL("Failed to link program"); 58848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 58948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 59048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 59148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Delete program object and all attached shaders 59248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 59348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 59448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid Utils::program::remove() 59548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 59648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* GL entry points */ 59748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 59848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 59948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Make sure program object is no longer used by GL */ 60048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.useProgram(0); 60148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 60248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Clean program object */ 60348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (0 != m_program_object_id) 60448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 60548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteProgram(m_program_object_id); 60648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_program_object_id = 0; 60748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 60848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 60948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Clean shaders */ 61048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (0 != m_compute_shader_id) 61148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 61248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteShader(m_compute_shader_id); 61348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_compute_shader_id = 0; 61448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 61548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 61648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (0 != m_fragment_shader_id) 61748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 61848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteShader(m_fragment_shader_id); 61948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_fragment_shader_id = 0; 62048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 62148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 62248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (0 != m_geometry_shader_id) 62348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 62448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteShader(m_geometry_shader_id); 62548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_geometry_shader_id = 0; 62648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 62748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 62848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (0 != m_tesselation_control_shader_id) 62948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 63048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteShader(m_tesselation_control_shader_id); 63148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_tesselation_control_shader_id = 0; 63248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 63348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 63448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (0 != m_tesselation_evaluation_shader_id) 63548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 63648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteShader(m_tesselation_evaluation_shader_id); 63748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_tesselation_evaluation_shader_id = 0; 63848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 63948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 64048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (0 != m_vertex_shader_id) 64148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 64248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteShader(m_vertex_shader_id); 64348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_vertex_shader_id = 0; 64448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 64548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 64648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 64748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Execute UseProgram 64848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 64948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 65048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid Utils::program::use() const 65148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 65248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 65348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 65448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.useProgram(m_program_object_id); 65548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "UseProgram"); 65648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 65748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 65848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Constructor. 65948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 66048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param context CTS context. 66148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 66248087f5f0eb08759ee763f98daf3b34becb74559Pyry HaulosUtils::texture::texture(deqp::Context& context) : m_id(0), m_context(context) 66348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 66448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Nothing to done here */ 66548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 66648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 66748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Destructor 66848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 66948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 67048087f5f0eb08759ee763f98daf3b34becb74559Pyry HaulosUtils::texture::~texture() 67148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 67248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (0 != m_id) 67348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 67448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 67548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 67648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteTextures(1, &m_id); 67748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_id = 0; 67848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 67948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 68048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 68148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Bind texture to GL_TEXTURE_2D 68248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 68348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 68448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid Utils::texture::bind() 68548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 68648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 68748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 68848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.bindTexture(GL_TEXTURE_2D, m_id); 68948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture"); 69048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 69148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 69248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Create 2d texture 69348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 69448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param width Width of texture 69548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param height Height of texture 69648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param internal_format Internal format of texture 69748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 69848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid Utils::texture::create(glw::GLuint width, glw::GLuint height, glw::GLenum internal_format) 69948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 70048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 70148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 70248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.genTextures(1, &m_id); 70348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "GenTextures"); 70448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 70548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos bind(); 70648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 70748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.texStorage2D(GL_TEXTURE_2D, 1 /* levels */, internal_format, width, height); 70848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage2D"); 70948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 71048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 71148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Get contents of texture 71248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 71348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param format Format of image 71448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param type Type of image 71548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param out_data Buffer for image 71648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 71748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid Utils::texture::get(glw::GLenum format, glw::GLenum type, glw::GLvoid* out_data) 71848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 71948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 72048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 72148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos bind(); 72248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 72348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getTexImage(GL_TEXTURE_2D, 0, format, type, out_data); 72448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexImage"); 72548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 72648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 72748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Update contents of texture 72848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 72948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param width Width of texture 73048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param height Height of texture 73148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param format Format of data 73248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param type Type of data 73348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param data Buffer with image 73448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 73548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid Utils::texture::update(glw::GLuint width, glw::GLuint height, glw::GLenum format, glw::GLenum type, 73648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glw::GLvoid* data) 73748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 73848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 73948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 74048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos bind(); 74148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 74248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.texSubImage2D(GL_TEXTURE_2D, 0 /* level */, 0 /* x */, 0 /* y */, width, height, format, type, data); 74348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "TexSubImage2D"); 74448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 74548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 74648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Constructor. 74748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 74848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param context CTS context. 74948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 75048087f5f0eb08759ee763f98daf3b34becb74559Pyry HaulosUtils::vertexArray::vertexArray(deqp::Context& context) : m_id(0), m_context(context) 75148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 75248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 75348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 75448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Destructor 75548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 75648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 75748087f5f0eb08759ee763f98daf3b34becb74559Pyry HaulosUtils::vertexArray::~vertexArray() 75848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 75948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (0 != m_id) 76048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 76148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 76248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 76348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteVertexArrays(1, &m_id); 76448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 76548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_id = 0; 76648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 76748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 76848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 76948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Execute BindVertexArray 77048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 77148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 77248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid Utils::vertexArray::bind() 77348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 77448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 77548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 77648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.bindVertexArray(m_id); 77748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "BindVertexArray"); 77848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 77948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 78048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Execute GenVertexArrays 78148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 78248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 78348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid Utils::vertexArray::generate() 78448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 78548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 78648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 78748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.genVertexArrays(1, &m_id); 78848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "GenVertexArrays"); 78948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 79048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 79148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Builds a program object consisting of up to 5 shader stages 79248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * (vertex/tessellation control/tessellation evaluation/geometry/fragment). 79348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * The shaders are attached to the program object, then compiled. Finally, 79448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * the program object is linked. 79548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 79648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * XFB can be optionally configured for the program object. 79748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 79848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * Should an error be reported by GL implementation, a TestError 79948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * exception will be thrown. 80048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 80148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param gl OpenGL functions from the active rendering context. 80248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param vs_body Body to use for the vertex shader. Can be an empty string. 80348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param tc_body Body to use for the tessellation control shader. Can be 80448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * an empty string. 80548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param te_body Body to use for the tessellation evaluation shader. Can be 80648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * an empty string. 80748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param gs_body Body to use for the geometry shader. Can be an empty string. 80848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param fs_body Body to use for the fragment shader. Can be an empty string. 80948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param xfb_varyings An array of names of varyings to use for XFB. Can be NULL. 81048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param n_xfb_varyings Amount of XFB varyings defined in @param xfb_varyings.Can be 0. 81148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param out_vs_id Deref will be used to store GL id of a generated vertex shader. 81248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * Can be NULL in which case no vertex shader will be used for the 81348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * program object. 81448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param out_tc_id Deref will be used to store GL id of a generated tess control shader. 81548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * Can be NULL in which case no tess control shader will be used for the 81648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * program object. 81748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param out_te_id Deref will be used to store GL id of a generated tess evaluation shader. 81848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * Can be NULL in which case no tess evaluation shader will be used for the 81948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * program object. 82048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param out_gs_id Deref will be used to store GL id of a generated geometry shader. 82148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * Can be NULL in which case no geometry shader will be used for the 82248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * program object. 82348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param out_fs_id Deref will be used to store GL id of a generated fragment shader. 82448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * Can be NULL in which case no fragment shader will be used for the 82548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * program object. 82648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param out_po_id Deref will be used to store GL id of a generated program object. 82748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * Must not be NULL. 82848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 82948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return true if the program was built successfully, false otherwise. 83048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * */ 83148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosbool Utils::buildProgram(const glw::Functions& gl, const std::string& vs_body, const std::string& tc_body, 83248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const std::string& te_body, const std::string& gs_body, const std::string& fs_body, 83348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::GLchar** xfb_varyings, const unsigned int& n_xfb_varyings, glw::GLuint* out_vs_id, 83448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glw::GLuint* out_tc_id, glw::GLuint* out_te_id, glw::GLuint* out_gs_id, glw::GLuint* out_fs_id, 83548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glw::GLuint* out_po_id) 83648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 83748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos bool result = false; 83848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 83948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Link the program object */ 84048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glw::GLint link_status = GL_FALSE; 84148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 84248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Create objects, set up shader bodies and attach all requested shaders to the program object */ 84348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *out_po_id = gl.createProgram(); 84448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call failed."); 84548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 84648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (out_vs_id != DE_NULL) 84748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 84848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* vs_body_raw_ptr = vs_body.c_str(); 84948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 85048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *out_vs_id = gl.createShader(GL_VERTEX_SHADER); 85148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call failed."); 85248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 85348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.attachShader(*out_po_id, *out_vs_id); 85448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader() call failed."); 85548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 85648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.shaderSource(*out_vs_id, 1 /* count */, &vs_body_raw_ptr, DE_NULL /* length */); 85748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed."); 85848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 85948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 86048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (out_tc_id != DE_NULL) 86148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 86248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* tc_body_raw_ptr = tc_body.c_str(); 86348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 86448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *out_tc_id = gl.createShader(GL_TESS_CONTROL_SHADER); 86548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call failed."); 86648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 86748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.attachShader(*out_po_id, *out_tc_id); 86848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader() call failed."); 86948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 87048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.shaderSource(*out_tc_id, 1 /* count */, &tc_body_raw_ptr, DE_NULL /* length */); 87148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed."); 87248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 87348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 87448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (out_te_id != DE_NULL) 87548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 87648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* te_body_raw_ptr = te_body.c_str(); 87748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 87848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *out_te_id = gl.createShader(GL_TESS_EVALUATION_SHADER); 87948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call failed."); 88048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 88148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.attachShader(*out_po_id, *out_te_id); 88248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader() call failed."); 88348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 88448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.shaderSource(*out_te_id, 1 /* count */, &te_body_raw_ptr, DE_NULL /* length */); 88548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed."); 88648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 88748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 88848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (out_gs_id != DE_NULL) 88948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 89048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* gs_body_raw_ptr = gs_body.c_str(); 89148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 89248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *out_gs_id = gl.createShader(GL_GEOMETRY_SHADER); 89348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call failed."); 89448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 89548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.attachShader(*out_po_id, *out_gs_id); 89648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader() call failed."); 89748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 89848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.shaderSource(*out_gs_id, 1 /* count */, &gs_body_raw_ptr, DE_NULL /* length */); 89948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed."); 90048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 90148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 90248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (out_fs_id != DE_NULL) 90348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 90448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* fs_body_raw_ptr = fs_body.c_str(); 90548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 90648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *out_fs_id = gl.createShader(GL_FRAGMENT_SHADER); 90748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call failed."); 90848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 90948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.attachShader(*out_po_id, *out_fs_id); 91048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader() call failed."); 91148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 91248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.shaderSource(*out_fs_id, 1 /* count */, &fs_body_raw_ptr, DE_NULL /* length */); 91348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed."); 91448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 91548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 91648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Compile all shaders */ 91748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::GLuint so_ids[] = { (out_vs_id != DE_NULL) ? *out_vs_id : 0, (out_tc_id != DE_NULL) ? *out_tc_id : 0, 91848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos (out_te_id != DE_NULL) ? *out_te_id : 0, (out_gs_id != DE_NULL) ? *out_gs_id : 0, 91948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos (out_fs_id != DE_NULL) ? *out_fs_id : 0 }; 92048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const unsigned int n_so_ids = sizeof(so_ids) / sizeof(so_ids[0]); 92148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 92248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (unsigned int n_so_id = 0; n_so_id < n_so_ids; ++n_so_id) 92348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 92448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glw::GLuint so_id = so_ids[n_so_id]; 92548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 92648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (so_id != 0) 92748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 92848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glw::GLint compile_status = GL_FALSE; 92948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 93048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.compileShader(so_id); 93148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader() call failed."); 93248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 93348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getShaderiv(so_id, GL_COMPILE_STATUS, &compile_status); 93448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv() call failed."); 93548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 93648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (compile_status != GL_TRUE) 93748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 93848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos goto end; 93948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 94048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } /* if (so_id != 0) */ 94148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } /* for (all shader objects) */ 94248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 94348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Set up XFB */ 94448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (xfb_varyings != NULL) 94548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 94648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.transformFeedbackVaryings(*out_po_id, n_xfb_varyings, xfb_varyings, GL_INTERLEAVED_ATTRIBS); 94748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings() call failed."); 94848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 94948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 95048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.linkProgram(*out_po_id); 95148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glLinkProgram() call failed."); 95248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 95348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getProgramiv(*out_po_id, GL_LINK_STATUS, &link_status); 95448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv() call failed."); 95548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 95648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (link_status != GL_TRUE) 95748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 95848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos goto end; 95948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 96048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 96148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* All done */ 96248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = true; 96348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 96448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosend: 96548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return result; 96648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 96748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 96848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Retrieves base variable type for user-specified variable type 96948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * (eg. float for vec4) 97048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 97148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param variable_type Variable type to use for the query. 97248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 97348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return As per description. 97448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 97548087f5f0eb08759ee763f98daf3b34becb74559Pyry HaulosUtils::_variable_type Utils::getBaseVariableType(const _variable_type& variable_type) 97648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 97748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos _variable_type result = VARIABLE_TYPE_UNKNOWN; 97848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 97948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos switch (variable_type) 98048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 98148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case VARIABLE_TYPE_BOOL: 98248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case VARIABLE_TYPE_BVEC2: 98348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case VARIABLE_TYPE_BVEC3: 98448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case VARIABLE_TYPE_BVEC4: 98548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 98648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = VARIABLE_TYPE_BOOL; 98748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 98848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 98948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 99048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 99148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case VARIABLE_TYPE_DOUBLE: 99248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case VARIABLE_TYPE_DVEC2: 99348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case VARIABLE_TYPE_DVEC3: 99448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case VARIABLE_TYPE_DVEC4: 99548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 99648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = VARIABLE_TYPE_DOUBLE; 99748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 99848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 99948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 100048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 100148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case VARIABLE_TYPE_FLOAT: 100248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case VARIABLE_TYPE_MAT2: 100348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case VARIABLE_TYPE_MAT2X3: 100448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case VARIABLE_TYPE_MAT2X4: 100548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case VARIABLE_TYPE_MAT3: 100648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case VARIABLE_TYPE_MAT3X2: 100748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case VARIABLE_TYPE_MAT3X4: 100848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case VARIABLE_TYPE_MAT4: 100948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case VARIABLE_TYPE_MAT4X2: 101048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case VARIABLE_TYPE_MAT4X3: 101148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case VARIABLE_TYPE_VEC2: 101248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case VARIABLE_TYPE_VEC3: 101348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case VARIABLE_TYPE_VEC4: 101448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 101548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = VARIABLE_TYPE_FLOAT; 101648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 101748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 101848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 101948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 102048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case VARIABLE_TYPE_INT: 102148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case VARIABLE_TYPE_IVEC2: 102248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case VARIABLE_TYPE_IVEC3: 102348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case VARIABLE_TYPE_IVEC4: 102448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 102548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = VARIABLE_TYPE_INT; 102648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 102748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 102848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 102948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 103048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case VARIABLE_TYPE_UINT: 103148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case VARIABLE_TYPE_UVEC2: 103248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case VARIABLE_TYPE_UVEC3: 103348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case VARIABLE_TYPE_UVEC4: 103448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 103548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = VARIABLE_TYPE_UINT; 103648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 103748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 103848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 103948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 104048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos default: 104148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 104248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos TCU_FAIL("Unrecognized variable type"); 104348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 104448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } /* switch (variable_type) */ 104548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 104648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return result; 104748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 104848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 104948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Retrieves size of a single component (in bytes) for user-specified 105048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * variable type. 105148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 105248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param variable_type Variable type to use for the query. 105348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 105448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return As per description. 105548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 105648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosunsigned int Utils::getComponentSizeForVariableType(const _variable_type& variable_type) 105748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 105848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos _variable_type base_variable_type = getBaseVariableType(variable_type); 105948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos unsigned int result = 0; 106048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 106148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos switch (base_variable_type) 106248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 106348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case VARIABLE_TYPE_BOOL: 106448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = sizeof(bool); 106548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 106648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case VARIABLE_TYPE_DOUBLE: 106748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = sizeof(double); 106848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 106948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case VARIABLE_TYPE_FLOAT: 107048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = sizeof(float); 107148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 107248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case VARIABLE_TYPE_INT: 107348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = sizeof(int); 107448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 107548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case VARIABLE_TYPE_UINT: 107648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = sizeof(unsigned int); 107748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 107848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 107948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos default: 108048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 108148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos TCU_FAIL("Unrecognized base variable type"); 108248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 108348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } /* switch (variable_type) */ 108448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 108548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return result; 108648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 108748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 108848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Retrieves a GLenum value corresponding to internal shader stage 108948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * representation. 109048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 109148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param shader_stage Shader stage to user for the query. 109248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 109348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return Requested value or GL_NONE if the stage was not recognized. 109448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 109548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosglw::GLenum Utils::getGLenumForShaderStage(const _shader_stage& shader_stage) 109648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 109748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glw::GLenum result = GL_NONE; 109848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 109948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos switch (shader_stage) 110048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 110148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case SHADER_STAGE_VERTEX: 110248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = GL_VERTEX_SHADER; 110348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 110448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case SHADER_STAGE_TESSELLATION_CONTROL: 110548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = GL_TESS_CONTROL_SHADER; 110648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 110748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case SHADER_STAGE_TESSELLATION_EVALUATION: 110848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = GL_TESS_EVALUATION_SHADER; 110948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 111048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case SHADER_STAGE_GEOMETRY: 111148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = GL_GEOMETRY_SHADER; 111248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 111348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case SHADER_STAGE_FRAGMENT: 111448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = GL_FRAGMENT_SHADER; 111548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 111648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 111748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos default: 111848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 111948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos TCU_FAIL("Unrecognized shader stage requested"); 112048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 112148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } /* switch (shader_stage) */ 112248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 112348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return result; 112448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 112548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 112648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Retrieves number of components that user-specified variable type supports. 112748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 112848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param variable_type GLSL variable type to use for the query. 112948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 113048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return As per description. 113148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 113248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosunsigned int Utils::getNumberOfComponentsForVariableType(const _variable_type& variable_type) 113348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 113448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos unsigned int result = 0; 113548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 113648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos switch (variable_type) 113748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 113848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case VARIABLE_TYPE_BOOL: 113948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case VARIABLE_TYPE_DOUBLE: 114048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case VARIABLE_TYPE_FLOAT: 114148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case VARIABLE_TYPE_INT: 114248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case VARIABLE_TYPE_UINT: 114348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 114448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = 1; 114548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 114648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 114748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 114848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 114948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case VARIABLE_TYPE_BVEC2: 115048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case VARIABLE_TYPE_DVEC2: 115148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case VARIABLE_TYPE_IVEC2: 115248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case VARIABLE_TYPE_UVEC2: 115348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case VARIABLE_TYPE_VEC2: 115448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 115548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = 2; 115648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 115748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 115848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 115948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 116048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case VARIABLE_TYPE_BVEC3: 116148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case VARIABLE_TYPE_DVEC3: 116248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case VARIABLE_TYPE_IVEC3: 116348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case VARIABLE_TYPE_UVEC3: 116448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case VARIABLE_TYPE_VEC3: 116548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 116648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = 3; 116748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 116848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 116948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 117048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 117148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case VARIABLE_TYPE_BVEC4: 117248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case VARIABLE_TYPE_DVEC4: 117348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case VARIABLE_TYPE_IVEC4: 117448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case VARIABLE_TYPE_MAT2: 117548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case VARIABLE_TYPE_UVEC4: 117648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case VARIABLE_TYPE_VEC4: 117748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 117848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = 4; 117948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 118048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 118148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 118248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 118348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case VARIABLE_TYPE_MAT2X3: 118448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case VARIABLE_TYPE_MAT3X2: 118548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 118648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = 6; 118748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 118848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 118948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 119048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 119148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case VARIABLE_TYPE_MAT2X4: 119248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case VARIABLE_TYPE_MAT4X2: 119348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 119448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = 8; 119548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 119648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 119748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 119848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 119948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case VARIABLE_TYPE_MAT3: 120048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 120148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = 9; 120248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 120348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 120448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 120548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 120648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case VARIABLE_TYPE_MAT3X4: 120748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case VARIABLE_TYPE_MAT4X3: 120848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 120948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = 12; 121048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 121148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 121248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 121348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 121448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case VARIABLE_TYPE_MAT4: 121548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 121648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = 16; 121748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 121848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 121948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 122048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 122148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos default: 122248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 122348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } /* switch (variable_type) */ 122448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 122548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return result; 122648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 122748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 122848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Retrieves a literal defining user-specified shader stage enum. 122948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 123048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param shader_stage Shader stage to use for the query. 123148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 123248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return Requested string or "?" if the stage was not recognized. 123348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 123448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosstd::string Utils::getShaderStageString(const _shader_stage& shader_stage) 123548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 123648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::string result = "?"; 123748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 123848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos switch (shader_stage) 123948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 124048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case SHADER_STAGE_FRAGMENT: 124148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = "Fragment Shader"; 124248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 124348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case SHADER_STAGE_GEOMETRY: 124448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = "Geometry Shader"; 124548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 124648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case SHADER_STAGE_TESSELLATION_CONTROL: 124748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = "Tessellation Control Shader"; 124848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 124948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case SHADER_STAGE_TESSELLATION_EVALUATION: 125048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = "Tessellation Evaluation Shader"; 125148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 125248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case SHADER_STAGE_VERTEX: 125348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = "Vertex Shader"; 125448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 125548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 125648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos default: 125748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 125848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos TCU_FAIL("Unrecognized shader stage"); 125948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 126048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } /* switch (shader_stage) */ 126148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 126248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return result; 126348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 126448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 126548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Retrieves a literal defining user-specified shader stage enum. 126648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 126748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param shader_stage_glenum Shader stage to use for the query. 126848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 126948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return Requested string or "?" if the stage was not recognized. 127048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 127148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosstd::string Utils::getShaderStageStringFromGLEnum(const glw::GLenum shader_stage_glenum) 127248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 127348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::string result = "?"; 127448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 127548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos switch (shader_stage_glenum) 127648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 127748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case GL_FRAGMENT_SHADER: 127848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = "Fragment Shader"; 127948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 128048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case GL_GEOMETRY_SHADER: 128148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = "Geometry Shader"; 128248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 128348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case GL_TESS_CONTROL_SHADER: 128448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = "Tessellation Control Shader"; 128548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 128648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case GL_TESS_EVALUATION_SHADER: 128748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = "Tessellation Evaluation Shader"; 128848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 128948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case GL_VERTEX_SHADER: 129048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = "Vertex Shader"; 129148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 129248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 129348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos default: 129448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 129548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos TCU_FAIL("Unrecognized shader string"); 129648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 129748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } /* switch (shader_stage_glenum) */ 129848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 129948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return result; 130048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 130148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 130248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Returns string that represents program interface name 130348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 130448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param program_interface Program interface 130548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 130648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return String representation of known program interface 130748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 130848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosconst GLchar* Utils::programInterfaceToStr(glw::GLenum program_interface) 130948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 131048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLchar* string = "Unknown program interface"; 131148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 131248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos switch (program_interface) 131348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 131448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case GL_VERTEX_SUBROUTINE: 131548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos string = "GL_VERTEX_SUBROUTINE"; 131648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 131748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case GL_VERTEX_SUBROUTINE_UNIFORM: 131848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos string = "GL_VERTEX_SUBROUTINE_UNIFORM"; 131948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 132048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos default: 132148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos TCU_FAIL("Not implemented"); 132248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 132348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos }; 132448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 132548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return string; 132648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 132748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 132848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Returns string that represents pname's name 132948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 133048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param pname pname 133148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 133248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return String representation of known pnames 133348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 133448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosconst GLchar* Utils::pnameToStr(glw::GLenum pname) 133548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 133648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLchar* string = "Unknown pname"; 133748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 133848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos switch (pname) 133948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 134048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case GL_ACTIVE_SUBROUTINE_UNIFORMS: 134148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos string = "GL_ACTIVE_SUBROUTINE_UNIFORMS"; 134248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 134348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS: 134448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos string = "GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS"; 134548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 134648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case GL_ACTIVE_SUBROUTINES: 134748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos string = "GL_ACTIVE_SUBROUTINES"; 134848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 134948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case GL_ACTIVE_SUBROUTINE_UNIFORM_MAX_LENGTH: 135048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos string = "GL_ACTIVE_SUBROUTINE_UNIFORM_MAX_LENGTH"; 135148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 135248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case GL_ACTIVE_SUBROUTINE_MAX_LENGTH: 135348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos string = "GL_ACTIVE_SUBROUTINE_MAX_LENGTH"; 135448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 135548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case GL_NUM_COMPATIBLE_SUBROUTINES: 135648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos string = "GL_NUM_COMPATIBLE_SUBROUTINES"; 135748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 135848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case GL_UNIFORM_SIZE: 135948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos string = "GL_UNIFORM_SIZE"; 136048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 136148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case GL_COMPATIBLE_SUBROUTINES: 136248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos string = "GL_COMPATIBLE_SUBROUTINES"; 136348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 136448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case GL_UNIFORM_NAME_LENGTH: 136548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos string = "GL_UNIFORM_NAME_LENGTH"; 136648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 136748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case GL_ACTIVE_RESOURCES: 136848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos string = "GL_ACTIVE_RESOURCES"; 136948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 137048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case GL_MAX_NAME_LENGTH: 137148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos string = "GL_MAX_NAME_LENGTH"; 137248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 137348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case GL_MAX_NUM_COMPATIBLE_SUBROUTINES: 137448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos string = "GL_MAX_NUM_COMPATIBLE_SUBROUTINES"; 137548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 137648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case GL_NAME_LENGTH: 137748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos string = "GL_NAME_LENGTH"; 137848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 137948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case GL_ARRAY_SIZE: 138048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos string = "GL_ARRAY_SIZE"; 138148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 138248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case GL_LOCATION: 138348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos string = "GL_LOCATION"; 138448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 138548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos default: 138648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos TCU_FAIL("Not implemented"); 138748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 138848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos }; 138948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 139048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return string; 139148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 139248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 139348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosbool Utils::compare(const glw::GLfloat& left, const glw::GLfloat& right) 139448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 139548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const glw::GLfloat m_epsilon = 0.00001f; 139648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 139748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_epsilon < std::abs(right - left)) 139848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 139948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return false; 140048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 140148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else 140248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 140348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return true; 140448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 140548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 140648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 140748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Returns a variable type enum corresponding to user-specified base variable type 140848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * and the number of components it should support. 140948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 141048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param base_variable_type Base variable type to use for the query. 141148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param n_components Number of components to consider for the query. 141248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 141348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return As per description. 141448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 141548087f5f0eb08759ee763f98daf3b34becb74559Pyry HaulosUtils::_variable_type Utils::getVariableTypeFromProperties(const _variable_type& base_variable_type, 141648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const unsigned int& n_components) 141748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 141848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos _variable_type result = VARIABLE_TYPE_UNKNOWN; 141948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 142048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos switch (base_variable_type) 142148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 142248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case VARIABLE_TYPE_BOOL: 142348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 142448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos switch (n_components) 142548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 142648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case 1: 142748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = VARIABLE_TYPE_BOOL; 142848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 142948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case 2: 143048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = VARIABLE_TYPE_BVEC2; 143148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 143248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case 3: 143348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = VARIABLE_TYPE_BVEC3; 143448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 143548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case 4: 143648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = VARIABLE_TYPE_BVEC4; 143748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 143848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 143948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos default: 144048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 144148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos TCU_FAIL("Unsupported number of components requested"); 144248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 144348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } /* switch (n_components) */ 144448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 144548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 144648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 144748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 144848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case VARIABLE_TYPE_DOUBLE: 144948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 145048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos switch (n_components) 145148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 145248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case 1: 145348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = VARIABLE_TYPE_DOUBLE; 145448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 145548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case 2: 145648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = VARIABLE_TYPE_DVEC2; 145748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 145848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case 3: 145948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = VARIABLE_TYPE_DVEC3; 146048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 146148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case 4: 146248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = VARIABLE_TYPE_DVEC4; 146348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 146448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 146548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos default: 146648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 146748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos TCU_FAIL("Unsupported number of components requested"); 146848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 146948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } /* switch (n_components) */ 147048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 147148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 147248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 147348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 147448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case VARIABLE_TYPE_FLOAT: 147548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 147648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos switch (n_components) 147748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 147848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case 1: 147948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = VARIABLE_TYPE_FLOAT; 148048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 148148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case 2: 148248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = VARIABLE_TYPE_VEC2; 148348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 148448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case 3: 148548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = VARIABLE_TYPE_VEC3; 148648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 148748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case 4: 148848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = VARIABLE_TYPE_VEC4; 148948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 149048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 149148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos default: 149248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 149348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos TCU_FAIL("Unsupported number of components requested"); 149448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 149548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } /* switch (n_components) */ 149648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 149748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 149848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 149948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 150048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case VARIABLE_TYPE_INT: 150148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 150248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos switch (n_components) 150348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 150448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case 1: 150548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = VARIABLE_TYPE_INT; 150648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 150748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case 2: 150848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = VARIABLE_TYPE_IVEC2; 150948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 151048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case 3: 151148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = VARIABLE_TYPE_IVEC3; 151248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 151348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case 4: 151448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = VARIABLE_TYPE_IVEC4; 151548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 151648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 151748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos default: 151848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 151948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos TCU_FAIL("Unsupported number of components requested"); 152048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 152148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } /* switch (n_components) */ 152248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 152348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 152448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 152548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 152648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case VARIABLE_TYPE_UINT: 152748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 152848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos switch (n_components) 152948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 153048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case 1: 153148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = VARIABLE_TYPE_UINT; 153248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 153348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case 2: 153448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = VARIABLE_TYPE_UVEC2; 153548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 153648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case 3: 153748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = VARIABLE_TYPE_UVEC3; 153848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 153948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case 4: 154048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = VARIABLE_TYPE_UVEC4; 154148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 154248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 154348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos default: 154448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 154548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos TCU_FAIL("Unsupported number of components requested"); 154648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 154748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } /* switch (n_components) */ 154848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 154948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 155048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 155148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 155248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos default: 155348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 155448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos TCU_FAIL("Unrecognized base variable type"); 155548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 155648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } /* switch (base_variable_type) */ 155748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 155848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return result; 155948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 156048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 156148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Returns a GLSL literal corresponding to user-specified variable type. 156248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 156348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param variable_type Variable type to use for the query. 156448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 156548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return As per description or [?] if @param variable_type was not 156648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * recognized. 156748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 156848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosstd::string Utils::getVariableTypeGLSLString(const _variable_type& variable_type) 156948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 157048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::string result = "[?]"; 157148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 157248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos switch (variable_type) 157348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 157448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case VARIABLE_TYPE_BOOL: 157548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = "bool"; 157648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 157748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case VARIABLE_TYPE_BVEC2: 157848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = "bvec2"; 157948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 158048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case VARIABLE_TYPE_BVEC3: 158148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = "bvec3"; 158248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 158348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case VARIABLE_TYPE_BVEC4: 158448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = "bvec4"; 158548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 158648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case VARIABLE_TYPE_DOUBLE: 158748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = "double"; 158848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 158948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case VARIABLE_TYPE_DVEC2: 159048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = "dvec2"; 159148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 159248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case VARIABLE_TYPE_DVEC3: 159348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = "dvec3"; 159448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 159548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case VARIABLE_TYPE_DVEC4: 159648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = "dvec4"; 159748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 159848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case VARIABLE_TYPE_FLOAT: 159948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = "float"; 160048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 160148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case VARIABLE_TYPE_INT: 160248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = "int"; 160348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 160448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case VARIABLE_TYPE_IVEC2: 160548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = "ivec2"; 160648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 160748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case VARIABLE_TYPE_IVEC3: 160848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = "ivec3"; 160948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 161048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case VARIABLE_TYPE_IVEC4: 161148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = "ivec4"; 161248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 161348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case VARIABLE_TYPE_MAT2: 161448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = "mat2"; 161548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 161648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case VARIABLE_TYPE_MAT2X3: 161748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = "mat2x3"; 161848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 161948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case VARIABLE_TYPE_MAT2X4: 162048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = "mat2x4"; 162148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 162248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case VARIABLE_TYPE_MAT3: 162348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = "mat3"; 162448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 162548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case VARIABLE_TYPE_MAT3X2: 162648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = "mat3x2"; 162748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 162848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case VARIABLE_TYPE_MAT3X4: 162948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = "mat3x4"; 163048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 163148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case VARIABLE_TYPE_MAT4: 163248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = "mat4"; 163348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 163448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case VARIABLE_TYPE_MAT4X2: 163548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = "mat4x2"; 163648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 163748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case VARIABLE_TYPE_MAT4X3: 163848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = "mat4x3"; 163948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 164048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case VARIABLE_TYPE_UINT: 164148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = "uint"; 164248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 164348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case VARIABLE_TYPE_UVEC2: 164448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = "uvec2"; 164548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 164648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case VARIABLE_TYPE_UVEC3: 164748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = "uvec3"; 164848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 164948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case VARIABLE_TYPE_UVEC4: 165048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = "uvec4"; 165148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 165248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case VARIABLE_TYPE_VEC2: 165348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = "vec2"; 165448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 165548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case VARIABLE_TYPE_VEC3: 165648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = "vec3"; 165748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 165848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case VARIABLE_TYPE_VEC4: 165948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = "vec4"; 166048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 166148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 166248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos default: 166348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 166448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos TCU_FAIL("Unrecognized variable type"); 166548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 166648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } /* switch (variable_type) */ 166748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 166848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return result; 166948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 167048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 167148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Constructor. 167248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 167348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param context Rendering context. 167448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 167548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 167648087f5f0eb08759ee763f98daf3b34becb74559Pyry HaulosAPITest1::APITest1(deqp::Context& context) 167748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos : TestCase(context, "min_maxes", "Verifies the implementation returns valid GL_MAX_SUBROUTINE* pnames " 167848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "which meet the minimum maximum requirements enforced by the spec.") 167948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_has_test_passed(true) 168048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 168148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Left blank intentionally */ 168248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 168348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 168448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Executes test iteration. 168548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 168648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed. 168748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos */ 168848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulostcu::TestNode::IterateResult APITest1::iterate() 168948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 169048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 169148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 169248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Do not execute the test if GL_ARB_shader_subroutine is not supported */ 169348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_shader_subroutine")) 169448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 169548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos throw tcu::NotSupportedError("GL_ARB_shader_subroutine is not supported."); 169648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 169748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 169848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Iterate over all pnames */ 169948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const struct 170048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 170148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glw::GLenum pname; 170248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* pname_string; 170348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glw::GLint min_value; 170448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } pnames[] = { { GL_MAX_SUBROUTINES, "GL_MAX_SUBROUTINES", 256 }, 170548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { GL_MAX_SUBROUTINE_UNIFORM_LOCATIONS, "GL_MAX_SUBROUTINE_UNIFORM_LOCATIONS", 1024 } }; 170648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const unsigned int n_pnames = sizeof(pnames) / sizeof(pnames[0]); 170748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 170848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (unsigned int n_pname = 0; n_pname < n_pnames; ++n_pname) 170948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 171048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glw::GLboolean bool_value = GL_FALSE; 171148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glw::GLdouble double_value = 0.0; 171248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glw::GLfloat float_value = 0.0f; 171348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glw::GLint int_value = 0; 171448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glw::GLint64 int64_value = 0; 171548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::GLint min_value = pnames[n_pname].min_value; 171648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::GLenum& pname = pnames[n_pname].pname; 171748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* pname_string = pnames[n_pname].pname_string; 171848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 171948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Retrieve the pname values */ 172048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getBooleanv(pname, &bool_value); 172148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glGetBooleanv() call failed."); 172248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 172348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getDoublev(pname, &double_value); 172448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glGetDoublev() call failed."); 172548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 172648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getFloatv(pname, &float_value); 172748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glGetFloatv() call failed."); 172848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 172948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getIntegerv(pname, &int_value); 173048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() call failed."); 173148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 173248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getInteger64v(pname, &int64_value); 173348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glGetInteger64v() call failed."); 173448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 173548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Make sure the value reported meets the min max requirement */ 173648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (int_value < min_value) 173748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 173848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.getLog() << tcu::TestLog::Message << "GL implementation reports a value of [" << int_value 173948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << "]" 174048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " for property [" 174148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << pname_string << "]" 174248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos ", whereas the min max for the property is [" 174348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << min_value << "]." << tcu::TestLog::EndMessage; 174448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 174548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_has_test_passed = false; 174648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 174748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 174848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Verify the other getters reported valid values */ 174948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const float epsilon = 1e-5f; 175048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 175148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (((int_value == 0) && (bool_value == GL_TRUE)) || ((int_value != 0) && (bool_value != GL_TRUE))) 175248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 175348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.getLog() << tcu::TestLog::Message << "Invalid boolean value [" << bool_value 175448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << "]" 175548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " reported for property [" 175648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << pname_string << "]" 175748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " (int value:[" 175848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << int_value << "])" << tcu::TestLog::EndMessage; 175948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 176048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_has_test_passed = false; 176148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 176248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 176348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (de::abs(double_value - (double)int_value) > epsilon) 176448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 176548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.getLog() << tcu::TestLog::Message << "Invalid double value [" << double_value 176648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << "]" 176748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " reported for property [" 176848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << pname_string << "]" 176948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " (int value:[" 177048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << int_value << "])" << tcu::TestLog::EndMessage; 177148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 177248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_has_test_passed = false; 177348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 177448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 177548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (de::abs(float_value - (float)int_value) > epsilon) 177648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 177748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.getLog() << tcu::TestLog::Message << "Invalid float value [" << float_value 177848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << "]" 177948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " reported for property [" 178048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << pname_string << "]" 178148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " (int value:[" 178248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << int_value << "])" << tcu::TestLog::EndMessage; 178348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 178448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_has_test_passed = false; 178548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 178648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 178748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (int64_value != int_value) 178848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 178948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.getLog() << tcu::TestLog::Message << "Invalid 64-bit integer value [" << float_value 179048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << "]" 179148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " reported for property [" 179248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << pname_string << "]" 179348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " (int value:[" 179448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << int_value << "])" << tcu::TestLog::EndMessage; 179548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 179648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_has_test_passed = false; 179748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 179848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } /* for (all pnames) */ 179948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 180048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_has_test_passed) 180148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 180248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 180348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 180448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else 180548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 180648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 180748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 180848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 180948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return STOP; 181048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 181148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 181248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Constructor. 181348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 181448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param context Rendering context. 181548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 181648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 181748087f5f0eb08759ee763f98daf3b34becb74559Pyry HaulosAPITest2::APITest2(deqp::Context& context) 181848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos : TestCase(context, "name_getters", "Verifies glGetActiveSubroutineName() and glGetActiveSubroutineUniformName() " 181948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "functions work correctly.") 182048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_buffer(DE_NULL) 182148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_has_test_passed(true) 182248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_po_id(0) 182348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_subroutine_name1("subroutine1") 182448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_subroutine_name2("subroutine2") 182548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_subroutine_uniform_name("data_provider") 182648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_vs_id(0) 182748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 182848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Left blank intentionally */ 182948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 183048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 183148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Destroys all ES objects that may have been created during test initialization, 183248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * as well as releases any buffers that may have been allocated during the process. 183348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos */ 183448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid APITest2::deinit() 183548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 183648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 183748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 183848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_buffer != DE_NULL) 183948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 184048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos delete[] m_buffer; 184148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 184248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_buffer = DE_NULL; 184348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 184448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 184548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_po_id != 0) 184648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 184748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteProgram(m_po_id); 184848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 184948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_po_id = 0; 185048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 185148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 185248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_vs_id != 0) 185348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 185448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteShader(m_vs_id); 185548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 185648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_vs_id = 0; 185748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 185848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 185948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 186048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Returns body of a vertex shader that should be used for the test. 186148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 186248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return As per description. 186348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 186448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosstd::string APITest2::getVertexShaderBody() 186548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 186648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return "#version 400\n" 186748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 186848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "#extension GL_ARB_shader_subroutine : require\n" 186948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 187048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine int ExampleSubroutineType(int example_argument);\n" 187148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 187248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine(ExampleSubroutineType) int subroutine1(int example_argument)\n" 187348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 187448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " return 1;\n" 187548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 187648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 187748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine(ExampleSubroutineType) int subroutine2(int example_argument)\n" 187848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 187948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " return 2;\n" 188048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 188148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 188248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine uniform ExampleSubroutineType data_provider;\n" 188348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 188448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void main()\n" 188548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 188648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " gl_Position = vec4(float(data_provider(0)), vec3(1) );\n" 188748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n"; 188848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 188948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 189048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Initializes all ES objects required to run the test. */ 189148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid APITest2::initTest() 189248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 189348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 189448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 189548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Generate program & shader objects */ 189648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_po_id = gl.createProgram(); 189748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_vs_id = gl.createShader(GL_VERTEX_SHADER); 189848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 189948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() or glCreateShader() call(s) failed."); 190048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 190148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Attach the shader to the program object */ 190248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.attachShader(m_po_id, m_vs_id); 190348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader() call failed."); 190448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 190548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Compile the shader */ 190648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glw::GLint compile_status = GL_FALSE; 190748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::string vs_body = getVertexShaderBody(); 190848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* vs_body_raw_ptr = vs_body.c_str(); 190948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 191048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.shaderSource(m_vs_id, 1 /* count */, &vs_body_raw_ptr, DE_NULL /* length */); 191148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed."); 191248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 191348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.compileShader(m_vs_id); 191448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader() call failed."); 191548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 191648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getShaderiv(m_vs_id, GL_COMPILE_STATUS, &compile_status); 191748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv() call failed."); 191848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 191948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (compile_status != GL_TRUE) 192048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 192148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos TCU_FAIL("Shader compilation failed."); 192248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 192348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 192448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Try to link the program object */ 192548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glw::GLint link_status = GL_FALSE; 192648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 192748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.linkProgram(m_po_id); 192848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glLinkProgram() call failed."); 192948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 193048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getProgramiv(m_po_id, GL_LINK_STATUS, &link_status); 193148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv() call failed."); 193248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 193348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (link_status != GL_TRUE) 193448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 193548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos TCU_FAIL("Program linking failed."); 193648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 193748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 193848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Perform a few sanity checks */ 193948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glw::GLint n_active_subroutines = 0; 194048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glw::GLint n_active_subroutine_uniforms = 0; 194148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 194248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getProgramStageiv(m_po_id, GL_VERTEX_SHADER, GL_ACTIVE_SUBROUTINES, &n_active_subroutines); 194348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getProgramStageiv(m_po_id, GL_VERTEX_SHADER, GL_ACTIVE_SUBROUTINE_UNIFORMS, &n_active_subroutine_uniforms); 194448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramStageiv() call failed."); 194548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 194648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (n_active_subroutines != 2 /* subroutines declared in vertex shader */) 194748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 194848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.getLog() << tcu::TestLog::Message << "Invalid amount of active subroutines reported; expected: 2," 194948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " reported:" 195048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << n_active_subroutines << tcu::TestLog::EndMessage; 195148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 195248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos TCU_FAIL("Invalid GL_ACTIVE_SUBROUTINES property value."); 195348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 195448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 195548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (n_active_subroutine_uniforms != 1) 195648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 195748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.getLog() << tcu::TestLog::Message 195848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << "Invalid amount of active subroutine uniforms reported: expected: 1," 195948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " reported: " 196048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << n_active_subroutine_uniforms << tcu::TestLog::EndMessage; 196148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 196248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos TCU_FAIL("Invalid GL_ACTIVE_SUBROUTINE_UNIFORMS property value."); 196348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 196448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 196548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 196648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Executes test iteration. 196748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 196848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed. 196948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos */ 197048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulostcu::TestNode::IterateResult APITest2::iterate() 197148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 197248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Do not execute the test if GL_ARB_shader_subroutine is not supported */ 197348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_shader_subroutine")) 197448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 197548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos throw tcu::NotSupportedError("GL_ARB_shader_subroutine is not supported."); 197648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 197748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 197848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Initialize a test program object */ 197948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos initTest(); 198048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 198148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Verify glGetActiveSubroutineName() works correctly */ 198248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos verifyGLGetActiveSubroutineNameFunctionality(); 198348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 198448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Verify glGetActiveSubroutineUniformName() works correctly */ 198548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos verifyGLGetActiveSubroutineUniformNameFunctionality(); 198648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 198748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Done */ 198848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_has_test_passed) 198948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 199048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 199148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 199248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else 199348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 199448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 199548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 199648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 199748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return STOP; 199848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 199948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 200048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Verifies glGetActiveSubroutineName() behaves as per GL_ARB_shader_subroutine 200148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * specification. 200248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 200348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid APITest2::verifyGLGetActiveSubroutineNameFunctionality() 200448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 200548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLsizei expected_length1 = (GLsizei)strlen(m_subroutine_name1) + 1; 200648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLsizei expected_length2 = (GLsizei)strlen(m_subroutine_name1) + 1; 200748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 200848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLsizei reported_length = 0; 200948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 201048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getActiveSubroutineName(m_po_id, GL_VERTEX_SHADER, 0, /* index */ 201148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 0, /* bufsize */ 201248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos DE_NULL, /* length */ 201348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos DE_NULL); /* name */ 201448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glGetActiveSubroutineName() call failed."); 201548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 201648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getProgramInterfaceiv(m_po_id, GL_VERTEX_SUBROUTINE, GL_MAX_NAME_LENGTH, &reported_length); 201748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glGetActiveSubroutineName() call failed."); 201848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 201948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if ((reported_length != expected_length1) && (reported_length != expected_length2)) 202048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 202148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.getLog() << tcu::TestLog::Message 202248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << "Invalid active subroutine name length reported:" << reported_length 202348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << ", instead of: " << expected_length1 << " or " << expected_length2 202448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << tcu::TestLog::EndMessage; 202548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 202648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos TCU_FAIL("Incorrect length of active subroutine name"); 202748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 202848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 202948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_buffer = new glw::GLchar[reported_length]; 203048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 203148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos memset(m_buffer, 0, reported_length); 203248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 203348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getActiveSubroutineName(m_po_id, GL_VERTEX_SHADER, 0, reported_length, DE_NULL, /* length */ 203448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_buffer); 203548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glGetActiveSubroutineName() call failed."); 203648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 203748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (strcmp(m_buffer, m_subroutine_name1) != 0 && strcmp(m_buffer, m_subroutine_name2) != 0) 203848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 203948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.getLog() << tcu::TestLog::Message << "Invalid active subroutine name reported:[" << m_buffer 204048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << "]" 204148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " instead of:[" 204248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << m_subroutine_name1 << "]" 204348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " or:[" 204448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << m_subroutine_name2 << "]." << tcu::TestLog::EndMessage; 204548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 204648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos TCU_FAIL("Invalid active subroutine name reported."); 204748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 204848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 204948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos delete[] m_buffer; 205048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_buffer = DE_NULL; 205148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 205248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 205348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Verifies glGetActiveSubroutineUniformName() behaves as per GL_ARB_shader_subroutine 205448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * specification. 205548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 205648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid APITest2::verifyGLGetActiveSubroutineUniformNameFunctionality() 205748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 205848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLsizei expected_length = (GLsizei)strlen(m_subroutine_uniform_name); 205948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 206048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLsizei reported_length = 0; 206148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 206248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getActiveSubroutineUniformName(m_po_id, GL_VERTEX_SHADER, 0, /* index */ 206348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 0, /* bufsize */ 206448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos DE_NULL, /* length */ 206548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos DE_NULL); /* name */ 206648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glGetActiveSubroutineUniformName() call failed."); 206748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 206848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getActiveSubroutineUniformName(m_po_id, GL_VERTEX_SHADER, 0, /* index */ 206948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 0, /* bufsize */ 207048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos &reported_length, DE_NULL); /* name */ 207148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glGetActiveSubroutineUniformName() call failed."); 207248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 207348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos // reported_length is the actual number of characters written into <name> 207448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos // If <bufSize> is 0, reported_length should be 0 207548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (reported_length != 0) 207648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 207748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.getLog() << tcu::TestLog::Message 207848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << "Invalid active subroutine uniform name length reported:" << reported_length 207948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << ", instead of: " << 0 << tcu::TestLog::EndMessage; 208048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 208148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos TCU_FAIL("Incorrect length of active subroutine uniform name"); 208248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 208348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 208448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_buffer = new glw::GLchar[expected_length + 1]; 208548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 208648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos memset(m_buffer, 0, expected_length + 1); 208748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 208848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getActiveSubroutineUniformName(m_po_id, GL_VERTEX_SHADER, 0, expected_length + 1, &reported_length, m_buffer); 208948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "getActiveSubroutineUniformName() call failed."); 209048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 209148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (reported_length != expected_length) 209248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 209348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.getLog() << tcu::TestLog::Message 209448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << "Invalid active subroutine uniform name length reported:" << reported_length 209548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << ", instead of: " << expected_length << tcu::TestLog::EndMessage; 209648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 209748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos TCU_FAIL("Incorrect length of active subroutine uniform name"); 209848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 209948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 210048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (strcmp(m_buffer, m_subroutine_uniform_name) != 0) 210148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 210248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.getLog() << tcu::TestLog::Message << "Invalid active subroutine uniform name reported:[" << m_buffer 210348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << "]" 210448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " instead of:[" 210548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << m_subroutine_uniform_name << "]" << tcu::TestLog::EndMessage; 210648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 210748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos TCU_FAIL("Invalid active subroutine uniform name reported."); 210848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 210948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 211048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos delete[] m_buffer; 211148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_buffer = DE_NULL; 211248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 211348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 211448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Constructor. 211548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 211648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param context Rendering context. 211748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 211848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 211948087f5f0eb08759ee763f98daf3b34becb74559Pyry HaulosFunctionalTest1_2::FunctionalTest1_2(deqp::Context& context) 212048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos : TestCase(context, "two_subroutines_single_subroutine_uniform", 212148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "Verifies the subroutines work correctly in a vertex shader for" 212248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " bool/float/int/uint/double/*vec*/*mat* argument and return types") 212348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_has_test_passed(true) 212448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_po_id(0) 212548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_po_getter0_subroutine_index(GL_INVALID_INDEX) 212648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_po_getter1_subroutine_index(GL_INVALID_INDEX) 212748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_po_subroutine_uniform_index(-1) 212848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_xfb_bo_id(0) 212948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_vao_id(0) 213048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_vs_id(0) 213148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 213248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Left blank intentionally */ 213348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 213448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 213548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Destroys all ES objects that may have been created during test initialization, 213648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * as well as releases any buffers that may have been allocated during the process. 213748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos */ 213848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid FunctionalTest1_2::deinit() 213948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 214048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 214148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 214248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos deinitTestIteration(); 214348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 214448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_xfb_bo_id != 0) 214548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 214648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteBuffers(1, &m_xfb_bo_id); 214748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 214848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_xfb_bo_id = 0; 214948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 215048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 215148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_vao_id != 0) 215248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 215348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteVertexArrays(1, &m_vao_id); 215448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 215548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_vao_id = 0; 215648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 215748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 215848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 215948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Deinitializes GL objects that are iteration-specific */ 216048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid FunctionalTest1_2::deinitTestIteration() 216148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 216248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 216348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 216448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_po_id != 0) 216548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 216648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteProgram(m_po_id); 216748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 216848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_po_id = 0; 216948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 217048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 217148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_vs_id != 0) 217248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 217348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteShader(m_vs_id); 217448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 217548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_vs_id = 0; 217648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 217748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 217848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 217948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Executes a single test iteration using user-specified test case propertiesz. 218048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 218148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param test-case Test case descriptor. 218248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 218348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return true if the test iteration passed, false otherwise. 218448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 218548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosbool FunctionalTest1_2::executeTestIteration(const _test_case& test_case) 218648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 218748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 218848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos bool result = true; 218948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 219048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Build the test program */ 219148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::string empty_body; 219248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::string vs_body = getVertexShaderBody(test_case.variable_type, test_case.array_size); 219348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::GLchar* xfb_varyings[] = { "result" }; 219448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const unsigned int n_xfb_varyings = sizeof(xfb_varyings) / sizeof(xfb_varyings[0]); 219548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 219648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!Utils::buildProgram(gl, vs_body, empty_body, empty_body, empty_body, empty_body, xfb_varyings, n_xfb_varyings, 219748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos &m_vs_id, NULL, /* out_tc_id */ 219848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos NULL, /* out_te_id */ 219948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos NULL, /* out_gs_id */ 220048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos NULL, &m_po_id)) 220148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 220248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos TCU_FAIL("Test program failed to build."); 220348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 220448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 220548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Retrieve subroutine locations */ 220648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_po_getter0_subroutine_index = gl.getSubroutineIndex(m_po_id, GL_VERTEX_SHADER, "getter0"); 220748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_po_getter1_subroutine_index = gl.getSubroutineIndex(m_po_id, GL_VERTEX_SHADER, "getter1"); 220848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 220948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glGetSubroutineIndex() call(s) failed."); 221048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 221148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_po_getter0_subroutine_index == GL_INVALID_INDEX || m_po_getter1_subroutine_index == GL_INVALID_INDEX) 221248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 221348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos TCU_FAIL("At least one subroutine is considered inactive which is invalid."); 221448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 221548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 221648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Retrieve subroutine uniform location */ 221748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_po_subroutine_uniform_index = gl.getSubroutineUniformLocation(m_po_id, GL_VERTEX_SHADER, "colorGetterUniform"); 221848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 221948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glGetSubroutineUniformLocation() call failed."); 222048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 222148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_po_subroutine_uniform_index == -1) 222248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 222348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos TCU_FAIL("Subroutine uniform is considered inactive which is invalid."); 222448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 222548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 222648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Set up XFB BO storage */ 222748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const Utils::_variable_type base_variable_type = Utils::getBaseVariableType(test_case.variable_type); 222848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos unsigned int iteration_xfb_bo_size = Utils::getComponentSizeForVariableType(base_variable_type) * 222948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::getNumberOfComponentsForVariableType(test_case.variable_type); 223048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos unsigned int total_xfb_bo_size = 0; 223148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 223248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (base_variable_type == Utils::VARIABLE_TYPE_BOOL) 223348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 223448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Boolean varyings are not supported by OpenGL. Instead, we use ints to output 223548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * boolean values. */ 223648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos iteration_xfb_bo_size = static_cast<unsigned int>(iteration_xfb_bo_size * sizeof(int)); 223748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 223848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 223948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos total_xfb_bo_size = iteration_xfb_bo_size * 2 /* subroutines we will be testing */; 224048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 224148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, total_xfb_bo_size, DE_NULL /* data */, GL_STATIC_DRAW); 224248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() call failed."); 224348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 224448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Activate test program object */ 224548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.useProgram(m_po_id); 224648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed."); 224748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 224848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Run two iterations. Each iteration should invoke different subroutine. */ 224948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::GLuint subroutine_indices[] = { m_po_getter0_subroutine_index, m_po_getter1_subroutine_index }; 225048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const unsigned int n_subroutine_indices = sizeof(subroutine_indices) / sizeof(subroutine_indices[0]); 225148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 225248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (unsigned int n_subroutine_index = 0; n_subroutine_index < n_subroutine_indices; ++n_subroutine_index) 225348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 225448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Configure which subroutine should be used for the draw call */ 225548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glw::GLuint current_subroutine_index = subroutine_indices[n_subroutine_index]; 225648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 225748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.uniformSubroutinesuiv(GL_VERTEX_SHADER, 1 /* count */, ¤t_subroutine_index); 225848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glUniformSubroutinesuiv() call failed."); 225948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 226048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Update XFB binding so that we do not overwrite data XFBed in previous iterations */ 226148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.bindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, /* index */ 226248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_xfb_bo_id, iteration_xfb_bo_size * n_subroutine_index, iteration_xfb_bo_size); 226348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferRange() call failed."); 226448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 226548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Draw a single point */ 226648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.beginTransformFeedback(GL_POINTS); 226748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback() call failed."); 226848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 226948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.drawArrays(GL_POINTS, 0 /* first */, 1 /* count */); 227048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() call failed."); 227148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 227248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.endTransformFeedback(); 227348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback() call failed."); 227448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } /* for (all subroutine indices) */ 227548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 227648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Map the BO storage into process space */ 227748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const void* xfb_data_ptr = gl.mapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY); 227848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBuffer() call failed."); 227948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 228048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result &= verifyXFBData(xfb_data_ptr, test_case.variable_type); 228148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 228248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER); 228348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffeR() call failed."); 228448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 228548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return result; 228648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 228748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 228848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Retrieves body of a vertex shader that should be used to verify 228948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * subroutine support, given user-specified test iteration properties. 229048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 229148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param variable_type GLSL type that should be used for argument and 229248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * return type definition in a subroutine. This setting 229348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * also affects type of the only output variable in the shader. 229448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param array_size 1 if non-arrayed arguments/return types should be tested; 229548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 2 if arrayed arguments/return types should be tested. 229648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 229748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return Requested string. 229848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 229948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosstd::string FunctionalTest1_2::getVertexShaderBody(const Utils::_variable_type& variable_type, unsigned int array_size) 230048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 230148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::_variable_type base_variable_type = Utils::getBaseVariableType(variable_type); 230248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos unsigned int n_variable_type_components = Utils::getNumberOfComponentsForVariableType(variable_type); 230348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::stringstream result_sstream; 230448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::string variable_type_glsl = Utils::getVariableTypeGLSLString(variable_type); 230548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::stringstream variable_type_glsl_array_sstream; 230648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::stringstream variable_type_glsl_arrayed_sstream; 230748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 230848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos variable_type_glsl_arrayed_sstream << variable_type_glsl; 230948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 231048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (array_size > 1) 231148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 231248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos variable_type_glsl_array_sstream << "[" << array_size << "]"; 231348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos variable_type_glsl_arrayed_sstream << variable_type_glsl_array_sstream.str(); 231448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 231548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 231648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Form pre-amble */ 231748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "#version 400\n" 231848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 231948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "#extension GL_ARB_shader_subroutine : require\n"; 232048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 232148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (variable_type == Utils::VARIABLE_TYPE_DOUBLE) 232248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 232348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "#extension GL_ARB_gpu_shader_fp64 : require\n"; 232448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 232548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 232648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Form subroutine type declaration */ 232748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "\n" 232848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine " 232948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << variable_type_glsl_arrayed_sstream.str() << " colorGetter(in " << variable_type_glsl 233048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << " in_value" << variable_type_glsl_array_sstream.str() << ");\n" 233148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n"; 233248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 233348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Declare getter functions */ 233448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (int n_getter = 0; n_getter < 2; ++n_getter) 233548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 233648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "subroutine(colorGetter) " << variable_type_glsl_arrayed_sstream.str() << " getter" 233748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << n_getter << "(in " << variable_type_glsl << " in_value" 233848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << variable_type_glsl_array_sstream.str() << ")\n" 233948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n"; 234048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 234148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (array_size > 1) 234248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 234348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << variable_type_glsl << " temp" << variable_type_glsl_array_sstream.str() << ";\n"; 234448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 234548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 234648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (base_variable_type == Utils::VARIABLE_TYPE_BOOL) 234748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 234848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (array_size > 1) 234948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 235048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (unsigned int array_index = 0; array_index < array_size; ++array_index) 235148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 235248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << " temp[" << array_index << "]" 235348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " = " 235448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << ((n_getter == 0) ? ((variable_type_glsl == "bool") ? "!" : "not") : "") 235548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << "(in_value[" << array_index << "]);\n"; 235648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 235748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 235848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << " return temp;\n"; 235948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 236048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else 236148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 236248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << " return " 236348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << ((n_getter == 0) ? ((variable_type_glsl == "bool") ? "!" : "not") : "") 236448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << "(in_value);\n"; 236548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 236648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } /* if (base_variable_type == Utils::VARIABLE_TYPE_BOOL) */ 236748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else 236848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 236948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (array_size > 1) 237048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 237148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (unsigned int array_index = 0; array_index < array_size; ++array_index) 237248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 237348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << " temp[" << array_index << "]" 237448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " = in_value[" 237548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << array_index << "] + " << (n_getter + 1) << ";\n"; 237648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 237748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 237848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << " return temp;\n"; 237948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 238048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else 238148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 238248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << " return (in_value + " << (n_getter + 1) << ");\n"; 238348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 238448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 238548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 238648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "}\n"; 238748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } /* for (both getter functions) */ 238848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 238948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Declare subroutine uniform */ 239048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "subroutine uniform colorGetter colorGetterUniform;\n" 239148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n"; 239248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 239348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Declare output variable */ 239448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "out "; 239548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 239648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (base_variable_type == Utils::VARIABLE_TYPE_BOOL) 239748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 239848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::_variable_type result_as_int_variable_type = 239948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::getVariableTypeFromProperties(Utils::VARIABLE_TYPE_INT, n_variable_type_components); 240048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::string variable_type_glsl_as_int = Utils::getVariableTypeGLSLString(result_as_int_variable_type); 240148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 240248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << variable_type_glsl_as_int; 240348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 240448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else 240548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 240648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << variable_type_glsl; 240748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 240848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 240948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << " result;\n" 241048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n"; 241148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 241248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Declare main(): prepare input argument for the subroutine function */ 241348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "void main()\n" 241448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 241548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " " 241648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << variable_type_glsl << " temp"; 241748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 241848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (array_size > 1) 241948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 242048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "[" << array_size << "]"; 242148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos }; 242248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 242348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << ";\n"; 242448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 242548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (unsigned int array_index = 0; array_index < array_size; ++array_index) 242648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 242748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << " temp"; 242848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 242948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (array_size > 1) 243048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 243148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "[" << array_index << "]"; 243248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 243348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 243448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << " = " << variable_type_glsl << "("; 243548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 243648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (base_variable_type == Utils::VARIABLE_TYPE_BOOL) 243748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 243848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "true"; 243948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 244048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else 244148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 244248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (unsigned int n_component = 0; n_component < n_variable_type_components; ++n_component) 244348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 244448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "3"; 244548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 244648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (n_component != (n_variable_type_components - 1)) 244748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 244848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << ", "; 244948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 245048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } /* for (all components) */ 245148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 245248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 245348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << ");\n"; 245448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } /* for (all array indices) */ 245548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 245648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Declare main(): call the subroutine. Verify the input and write the result 245748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * to the output variable. 245848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 245948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (base_variable_type == Utils::VARIABLE_TYPE_BOOL) 246048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 246148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::_variable_type result_as_int_variable_type = 246248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::getVariableTypeFromProperties(Utils::VARIABLE_TYPE_INT, n_variable_type_components); 246348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::string variable_type_glsl_as_int = Utils::getVariableTypeGLSLString(result_as_int_variable_type); 246448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 246548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << variable_type_glsl_arrayed_sstream.str() << " subroutine_result = colorGetterUniform(temp);\n" 246648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "result = "; 246748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 246848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (unsigned int array_index = 0; array_index < array_size; ++array_index) 246948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 247048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (variable_type_glsl == "bool") 247148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "bool(subroutine_result"; 247248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else 247348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "all(subroutine_result"; 247448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 247548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (array_size > 1) 247648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 247748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "[" << array_index << "]"; 247848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 247948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 248048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << ")"; 248148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 248248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (array_index != (array_size - 1)) 248348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 248448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "&& "; 248548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 248648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 248748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 248848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << " == true ? " << variable_type_glsl_as_int << "(1) : " << variable_type_glsl_as_int << "(0);"; 248948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 249048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else 249148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 249248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (array_size > 1) 249348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 249448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos DE_ASSERT(array_size == 2); 249548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 249648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << variable_type_glsl << " subroutine_result" << variable_type_glsl_array_sstream.str() 249748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << " = colorGetterUniform(temp);\n" 249848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 249948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "if (subroutine_result[0] == subroutine_result[1]) result = subroutine_result[0];\n" 250048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "else\n" 250148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "result = " 250248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << variable_type_glsl << "(-1);\n"; 250348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 250448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else 250548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 250648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "result = colorGetterUniform(temp);\n"; 250748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 250848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 250948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 251048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* All done */ 251148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "}\n"; 251248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 251348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return result_sstream.str(); 251448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 251548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 251648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Initializes all GL objects required to run the test. */ 251748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid FunctionalTest1_2::initTest() 251848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 251948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 252048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 252148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Generate buffer object to hold result XFB data */ 252248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.genBuffers(1, &m_xfb_bo_id); 252348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers() call failed."); 252448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 252548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Set up XFB BO bindings */ 252648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_xfb_bo_id); 252748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() call failed."); 252848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 252948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* index */, m_xfb_bo_id); 253048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase() call failed."); 253148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 253248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Generate VAO to use for the draw calls */ 253348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.genVertexArrays(1, &m_vao_id); 253448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays() call failed."); 253548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 253648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.bindVertexArray(m_vao_id); 253748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() call failed."); 253848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 253948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 254048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Executes test iteration. 254148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 254248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed. 254348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos */ 254448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulostcu::TestNode::IterateResult FunctionalTest1_2::iterate() 254548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 254648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Do not execute the test if GL_ARB_shader_subroutine is not supported */ 254748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_shader_subroutine")) 254848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 254948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos throw tcu::NotSupportedError("GL_ARB_shader_subroutine is not supported."); 255048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 255148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 255248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Initialize a test program object */ 255348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos initTest(); 255448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 255548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Construct test case descriptors: first, iIerate over all 255648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * variable types we want to cover */ 255748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const Utils::_variable_type variable_types[] = { 255848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::VARIABLE_TYPE_BOOL, Utils::VARIABLE_TYPE_BVEC2, Utils::VARIABLE_TYPE_BVEC3, 255948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::VARIABLE_TYPE_BVEC4, Utils::VARIABLE_TYPE_DOUBLE, Utils::VARIABLE_TYPE_FLOAT, 256048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::VARIABLE_TYPE_INT, Utils::VARIABLE_TYPE_IVEC2, Utils::VARIABLE_TYPE_IVEC3, 256148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::VARIABLE_TYPE_IVEC4, Utils::VARIABLE_TYPE_MAT2, Utils::VARIABLE_TYPE_MAT2X3, 256248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::VARIABLE_TYPE_MAT2X4, Utils::VARIABLE_TYPE_MAT3, Utils::VARIABLE_TYPE_MAT3X2, 256348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::VARIABLE_TYPE_MAT3X4, Utils::VARIABLE_TYPE_MAT4, Utils::VARIABLE_TYPE_MAT4X2, 256448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::VARIABLE_TYPE_MAT4X3, Utils::VARIABLE_TYPE_UINT, Utils::VARIABLE_TYPE_UVEC2, 256548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::VARIABLE_TYPE_UVEC3, Utils::VARIABLE_TYPE_UVEC4, Utils::VARIABLE_TYPE_VEC2, 256648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::VARIABLE_TYPE_VEC3, Utils::VARIABLE_TYPE_VEC4 256748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos }; 256848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const unsigned int n_variable_types = sizeof(variable_types) / sizeof(variable_types[0]); 256948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 257048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (unsigned int n_variable_type = 0; n_variable_type < n_variable_types; ++n_variable_type) 257148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 257248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::_variable_type current_variable_type = variable_types[n_variable_type]; 257348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 257448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* We need to test both arrayed and non-arrayed arguments */ 257548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (unsigned int array_size = 1; array_size < 3; ++array_size) 257648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 257748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Exclude double variables if the relevant extension is unavailable */ 257848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_gpu_shader_fp64") && 257948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos current_variable_type == Utils::VARIABLE_TYPE_DOUBLE) 258048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 258148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos continue; 258248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 258348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 258448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Form the descriptor */ 258548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos _test_case test_case; 258648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 258748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos test_case.array_size = array_size; 258848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos test_case.variable_type = current_variable_type; 258948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 259048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Store the test case descriptor */ 259148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_test_cases.push_back(test_case); 259248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } /* for (both arrayed and non-arrayed arguments) */ 259348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } /* for (all variable types) */ 259448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 259548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Iterate over all test cases and execute the test */ 259648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (_test_cases_const_iterator test_case_iterator = m_test_cases.begin(); test_case_iterator != m_test_cases.end(); 259748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos ++test_case_iterator) 259848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 259948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const _test_case& test_case = *test_case_iterator; 260048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 260148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_has_test_passed &= executeTestIteration(test_case); 260248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 260348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Release GL objects that were created during the execution */ 260448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos deinitTestIteration(); 260548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } /* for (all test cases) */ 260648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 260748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Done */ 260848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_has_test_passed) 260948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 261048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 261148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 261248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else 261348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 261448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 261548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 261648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 261748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return STOP; 261848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 261948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 262048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Verifies data that has been XFBed out by the vertex shader. 262148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 262248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param xfb_data Buffer holding the data. 262348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param variable_type GLSL type used for the test iteration 262448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * that generated the data at @param xfb_data. 262548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 262648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return true if the data was found to be valid, false if it 262748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * was detected to be incorrect. 262848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 262948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosbool FunctionalTest1_2::verifyXFBData(const void* xfb_data, const Utils::_variable_type& variable_type) 263048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 263148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const Utils::_variable_type base_variable_type = Utils::getBaseVariableType(variable_type); 263248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const float epsilon = 1e-5f; 263348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const unsigned int n_variable_type_components = Utils::getNumberOfComponentsForVariableType(variable_type); 263448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos bool result = true; 263548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const unsigned char* traveller_ptr = (const unsigned char*)xfb_data; 263648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 263748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Boolean arguments/return types are tested with a slightly different shader so we 263848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * need to test them in a separate code-path. 263948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos */ 264048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (base_variable_type == Utils::VARIABLE_TYPE_BOOL) 264148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 264248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* 0 should be returned when getter0 is used, 1 otherwise */ 264348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const unsigned int ref_values[] = { 0, 1 }; 264448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const unsigned int n_ref_values = sizeof(ref_values) / sizeof(ref_values[0]); 264548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 264648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (unsigned int n_ref_value = 0; n_ref_value < n_ref_values; ++n_ref_value) 264748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 264848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const unsigned int ref_value = ref_values[n_ref_value]; 264948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 265048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (unsigned int n_component = 0; n_component < n_variable_type_components; ++n_component) 265148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 265248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos int* result_value_ptr = (int*)(traveller_ptr); 265348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 265448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (*result_value_ptr != (int)ref_value) 265548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 265648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.getLog() << tcu::TestLog::Message << "Invalid value reported by subroutine using " 265748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "[" 265848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << Utils::getVariableTypeGLSLString(variable_type) << "]" 265948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << " argument/return types (" 266048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "expected:[" 266148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << ref_value << "], found:[" << *result_value_ptr << "])" 266248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << tcu::TestLog::EndMessage; 266348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 266448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = false; 266548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 266648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 266748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 266848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos traveller_ptr += sizeof(int); 266948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } /* for (all components) */ 267048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } /* for (all reference values) */ 267148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } /* if (base_variable_type == Utils::VARIABLE_TYPE_BOOL) */ 267248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else 267348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 267448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* 4 should be returned when getter0 is used, 5 otherwise */ 267548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const unsigned int ref_values[] = { 4, 5 }; 267648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const unsigned int n_ref_values = sizeof(ref_values) / sizeof(ref_values[0]); 267748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 267848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (unsigned int n_ref_value = 0; n_ref_value < n_ref_values; ++n_ref_value) 267948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 268048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const unsigned int ref_value = ref_values[n_ref_value]; 268148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 268248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos DE_ASSERT( 268348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos base_variable_type == Utils::VARIABLE_TYPE_DOUBLE || base_variable_type == Utils::VARIABLE_TYPE_FLOAT || 268448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos base_variable_type == Utils::VARIABLE_TYPE_INT || base_variable_type == Utils::VARIABLE_TYPE_UINT); 268548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 268648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (unsigned int n_component = 0; n_component < n_variable_type_components; ++n_component) 268748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 268848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const double* double_value_ptr = (double*)traveller_ptr; 268948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const float* float_value_ptr = (float*)traveller_ptr; 269048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const int* int_value_ptr = (int*)traveller_ptr; 269148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 269248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos switch (base_variable_type) 269348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 269448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case Utils::VARIABLE_TYPE_DOUBLE: 269548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 269648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (de::abs(*double_value_ptr - (double)ref_value) > epsilon) 269748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 269848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.getLog() << tcu::TestLog::Message << "Invalid value reported by subroutine using " 269948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "[" 270048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << Utils::getVariableTypeGLSLString(variable_type) << "]" 270148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << " argument/return types (" 270248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "expected:[" 270348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << ref_value << "], found:[" << *double_value_ptr << "])" 270448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << tcu::TestLog::EndMessage; 270548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 270648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = false; 270748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 270848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 270948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos traveller_ptr += sizeof(double); 271048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 271148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 271248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 271348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case Utils::VARIABLE_TYPE_FLOAT: 271448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 271548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (de::abs(*float_value_ptr - (float)ref_value) > epsilon) 271648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 271748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.getLog() << tcu::TestLog::Message << "Invalid value reported by subroutine using " 271848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "[" 271948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << Utils::getVariableTypeGLSLString(variable_type) << "]" 272048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << " argument/return types (" 272148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "expected:[" 272248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << ref_value << "], found:[" << *float_value_ptr << "])" 272348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << tcu::TestLog::EndMessage; 272448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 272548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = false; 272648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 272748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 272848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos traveller_ptr += sizeof(float); 272948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 273048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 273148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 273248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case Utils::VARIABLE_TYPE_INT: 273348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case Utils::VARIABLE_TYPE_UINT: 273448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 273548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (*int_value_ptr != (int)ref_value) 273648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 273748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.getLog() << tcu::TestLog::Message << "Invalid value reported by subroutine using " 273848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "[" 273948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << Utils::getVariableTypeGLSLString(variable_type) << "]" 274048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << " argument/return types (" 274148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "expected:[" 274248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << ref_value << "], found:[" << *int_value_ptr << "])" 274348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << tcu::TestLog::EndMessage; 274448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 274548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = false; 274648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 274748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 274848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos traveller_ptr += sizeof(int); 274948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 275048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 275148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 275248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos default: 275348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 275448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } /* switch (base_variable_type) */ 275548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } /* for (all components) */ 275648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } /* for (all reference values) */ 275748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 275848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 275948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return result; 276048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 276148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 276248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Constructor 276348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 276448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param context CTS context 276548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 276648087f5f0eb08759ee763f98daf3b34becb74559Pyry HaulosFunctionalTest3_4::FunctionalTest3_4(deqp::Context& context) 276748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos : TestCase(context, "four_subroutines_with_two_uniforms", "Verify Get* API and draw calls") 276848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_n_active_subroutine_uniforms(0) 276948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_n_active_subroutine_uniform_locations(0) 277048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_n_active_subroutines(0) 277148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_n_active_subroutine_uniform_name_length(0) 277248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_n_active_subroutine_name_length(0) 277348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_n_active_subroutine_uniform_size(0) 277448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 277548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Nothing to be done here */ 277648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 277748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 277848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Execute test 277948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 278048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return tcu::TestNode::STOP 278148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 278248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulostcu::TestNode::IterateResult FunctionalTest3_4::iterate() 278348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 278448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const glw::GLchar* vertex_shader_code = 278548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "#version 400 core\n" 278648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "#extension GL_ARB_shader_subroutine : require\n" 278748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 278848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "precision highp float;\n" 278948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 279048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "// Sub routine type declaration\n" 279148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine vec4 routine_type(in vec4 iparam);\n" 279248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 279348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "// Sub routine definitions\n" 279448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine(routine_type) vec4 inverse_order(in vec4 iparam)\n" 279548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 279648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " return iparam.wzyx;\n" 279748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 279848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 279948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine(routine_type) vec4 negate(in vec4 iparam)\n" 280048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 280148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " return -iparam;\n" 280248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 280348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 280448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine(routine_type) vec4 inverse(in vec4 iparam)\n" 280548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 280648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " return 1 / iparam;\n" 280748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 280848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 280948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine(routine_type) vec4 square(in vec4 iparam)\n" 281048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 281148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " return iparam * iparam;\n" 281248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 281348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 281448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "// Sub routine uniforms\n" 281548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine uniform routine_type first_routine;\n" 281648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine uniform routine_type second_routine;\n" 281748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 281848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "// Input data\n" 281948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "uniform vec4 input_data;\n" 282048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 282148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "// Output\n" 282248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "out vec4 out_input_data;\n" 282348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "out vec4 out_result_from_first_routine;\n" 282448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "out vec4 out_result_from_second_routine;\n" 282548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "out vec4 out_result_from_combined_routines;\n" 282648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "out vec4 out_result_from_routines_combined_in_reveresed_order;\n" 282748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 282848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void main()\n" 282948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 283048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " out_input_data = input_data;\n" 283148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " out_result_from_first_routine = first_routine(input_data);\n" 283248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " out_result_from_second_routine = second_routine(input_data);\n" 283348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " out_result_from_combined_routines = second_routine(first_routine(input_data));\n" 283448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " out_result_from_routines_combined_in_reveresed_order = first_routine(second_routine(input_data));\n" 283548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 283648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n"; 283748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 283848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLchar* varying_names[] = { 283948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "out_input_data", 284048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "out_result_from_first_routine", 284148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "out_result_from_second_routine", 284248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "out_result_from_combined_routines", 284348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "out_result_from_routines_combined_in_reveresed_order", 284448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos }; 284548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 284648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLchar* subroutine_uniform_names[] = { "first_routine", "second_routine" }; 284748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 284848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLchar* subroutine_names[] = { "inverse_order", "negate", "inverse", "square" }; 284948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 285048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLuint n_varyings = sizeof(varying_names) / sizeof(varying_names[0]); 285148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLuint transform_feedback_buffer_size = n_varyings * sizeof(GLfloat) * 4 /* vec4 */; 285248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 285348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLuint inverse_order_routine_index = 0; 285448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLuint negate_routine_index = 1; 285548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLuint inverse_routine_index = 2; 285648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLuint square_routine_index = 3; 285748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 285848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Test data */ 285948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const Utils::vec4<GLfloat> inverse_order_negate_data[5] = { 286048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::vec4<GLfloat>(-2.0f, -1.0f, 1.0f, 2.0f), Utils::vec4<GLfloat>(2.0f, 1.0f, -1.0f, -2.0f), 286148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::vec4<GLfloat>(2.0f, 1.0f, -1.0f, -2.0f), Utils::vec4<GLfloat>(-2.0f, -1.0f, 1.0f, 2.0f), 286248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::vec4<GLfloat>(-2.0f, -1.0f, 1.0f, 2.0f), 286348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos }; 286448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 286548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const Utils::vec4<GLfloat> inverse_order_inverse_data[5] = { 286648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::vec4<GLfloat>(-2.0f, -1.0f, 1.0f, 2.0f), Utils::vec4<GLfloat>(2.0f, 1.0f, -1.0f, -2.0f), 286748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::vec4<GLfloat>(-0.5f, -1.0f, 1.0f, 0.5f), Utils::vec4<GLfloat>(0.5f, 1.0f, -1.0f, -0.5f), 286848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::vec4<GLfloat>(0.5f, 1.0f, -1.0f, -0.5f), 286948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos }; 287048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 287148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const Utils::vec4<GLfloat> inverse_order_square_data[5] = { 287248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::vec4<GLfloat>(-2.0f, -1.0f, 1.0f, 2.0f), Utils::vec4<GLfloat>(2.0f, 1.0f, -1.0f, -2.0f), 287348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::vec4<GLfloat>(4.0f, 1.0f, 1.0f, 4.0f), Utils::vec4<GLfloat>(4.0f, 1.0f, 1.0f, 4.0f), 287448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::vec4<GLfloat>(4.0f, 1.0f, 1.0f, 4.0f), 287548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos }; 287648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 287748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const Utils::vec4<GLfloat> negate_inverse_data[5] = { 287848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::vec4<GLfloat>(-2.0f, -1.0f, 1.0f, 2.0f), Utils::vec4<GLfloat>(2.0f, 1.0f, -1.0f, -2.0f), 287948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::vec4<GLfloat>(-0.5f, -1.0f, 1.0f, 0.5f), Utils::vec4<GLfloat>(0.5f, 1.0f, -1.0f, -0.5f), 288048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::vec4<GLfloat>(0.5f, 1.0f, -1.0f, -0.5f), 288148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos }; 288248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 288348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const Utils::vec4<GLfloat> negate_square_data[5] = { 288448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::vec4<GLfloat>(-2.0f, -1.0f, 1.0f, 2.0f), Utils::vec4<GLfloat>(2.0f, 1.0f, -1.0f, -2.0f), 288548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::vec4<GLfloat>(4.0f, 1.0f, 1.0f, 4.0f), Utils::vec4<GLfloat>(4.0f, 1.0f, 1.0f, 4.0f), 288648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::vec4<GLfloat>(-4.0f, -1.0f, -1.0f, -4.0f), 288748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos }; 288848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 288948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const Utils::vec4<GLfloat> inverse_square_data[5] = { 289048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::vec4<GLfloat>(-2.0f, -1.0f, 1.0f, 2.0f), Utils::vec4<GLfloat>(-0.5f, -1.0f, 1.0f, 0.5f), 289148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::vec4<GLfloat>(4.0f, 1.0f, 1.0f, 4.0f), Utils::vec4<GLfloat>(0.25f, 1.0f, 1.0f, 0.25f), 289248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::vec4<GLfloat>(0.25f, 1.0f, 1.0f, 0.25f), 289348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos }; 289448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 289548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Do not execute the test if GL_ARB_shader_subroutine is not supported */ 289648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_shader_subroutine")) 289748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 289848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos throw tcu::NotSupportedError("GL_ARB_shader_subroutine is not supported."); 289948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 290048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 290148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_n_active_subroutine_uniforms = 2; 290248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_n_active_subroutine_uniform_locations = 2; 290348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_n_active_subroutines = 4; 290448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_n_active_subroutine_uniform_name_length = 0; 290548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_n_active_subroutine_name_length = 0; 290648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_n_active_subroutine_uniform_size = 1; 290748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 290848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* GL objects */ 290948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::program program(m_context); 291048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::buffer transform_feedback_buffer(m_context); 291148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::vertexArray vao(m_context); 291248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 291348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos bool result = true; 291448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 291548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Calculate max name lengths for subroutines and subroutine uniforms */ 291648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLint i = 0; i < m_n_active_subroutine_uniforms; ++i) 291748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 291848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLsizei length = (GLsizei)strlen(subroutine_uniform_names[i]); 291948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 292048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (length > m_n_active_subroutine_uniform_name_length) 292148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 292248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_n_active_subroutine_uniform_name_length = length; 292348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 292448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 292548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 292648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLint i = 0; i < m_n_active_subroutines; ++i) 292748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 292848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLsizei length = (GLsizei)strlen(subroutine_names[i]); 292948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 293048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (length > m_n_active_subroutine_name_length) 293148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 293248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_n_active_subroutine_name_length = length; 293348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 293448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 293548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 293648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Init */ 293748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos program.build(0 /* cs */, 0 /* fs */, 0 /* gs */, 0 /* tcs */, 0 /* test */, vertex_shader_code, varying_names, 293848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos n_varyings); 293948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 294048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos vao.generate(); 294148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos vao.bind(); 294248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 294348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos transform_feedback_buffer.generate(); 294448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos transform_feedback_buffer.update(GL_TRANSFORM_FEEDBACK_BUFFER, transform_feedback_buffer_size, 0 /* data */, 294548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GL_DYNAMIC_COPY); 294648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos transform_feedback_buffer.bindRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, 0, transform_feedback_buffer_size); 294748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 294848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos program.use(); 294948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 295048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Inspect Get* API */ 295148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if ((false == inspectProgramStageiv(program.m_program_object_id)) || 295248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos (false == inspectActiveSubroutineUniformiv(program.m_program_object_id, subroutine_uniform_names)) || 295348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos (false == inspectActiveSubroutineUniformName(program.m_program_object_id, subroutine_uniform_names)) || 295448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos (false == inspectActiveSubroutineName(program.m_program_object_id, subroutine_names)) || 295548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos (false == 295648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos inspectSubroutineBinding(program.m_program_object_id, subroutine_names, subroutine_uniform_names, false))) 295748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 295848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = false; 295948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 296048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 296148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Inspect GetProgram* API */ 296248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (true == m_context.getContextInfo().isExtensionSupported("GL_ARB_program_interface_query")) 296348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 296448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if ((false == inspectProgramInterfaceiv(program.m_program_object_id)) || 296548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos (false == 296648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos inspectProgramResourceiv(program.m_program_object_id, subroutine_names, subroutine_uniform_names)) || 296748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos (false == 296848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos inspectSubroutineBinding(program.m_program_object_id, subroutine_names, subroutine_uniform_names, true))) 296948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 297048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = false; 297148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 297248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 297348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 297448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Test shader execution */ 297548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if ((false == testDraw(program.m_program_object_id, subroutine_names[inverse_order_routine_index], 297648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos subroutine_names[negate_routine_index], subroutine_uniform_names, inverse_order_negate_data, 297748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos false)) || 297848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos (false == testDraw(program.m_program_object_id, subroutine_names[inverse_order_routine_index], 297948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos subroutine_names[inverse_routine_index], subroutine_uniform_names, 298048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos inverse_order_inverse_data, false)) || 298148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos (false == testDraw(program.m_program_object_id, subroutine_names[inverse_order_routine_index], 298248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos subroutine_names[square_routine_index], subroutine_uniform_names, inverse_order_square_data, 298348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos false)) || 298448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos (false == testDraw(program.m_program_object_id, subroutine_names[negate_routine_index], 298548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos subroutine_names[inverse_routine_index], subroutine_uniform_names, negate_inverse_data, 298648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos false)) || 298748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos (false == testDraw(program.m_program_object_id, subroutine_names[negate_routine_index], 298848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos subroutine_names[square_routine_index], subroutine_uniform_names, negate_square_data, 298948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos false)) || 299048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos (false == testDraw(program.m_program_object_id, subroutine_names[inverse_routine_index], 299148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos subroutine_names[square_routine_index], subroutine_uniform_names, inverse_square_data, 299248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos false))) 299348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 299448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = false; 299548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 299648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 299748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (true == m_context.getContextInfo().isExtensionSupported("GL_ARB_program_interface_query")) 299848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 299948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if ((false == testDraw(program.m_program_object_id, subroutine_names[inverse_order_routine_index], 300048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos subroutine_names[negate_routine_index], subroutine_uniform_names, 300148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos inverse_order_negate_data, true)) || 300248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos (false == testDraw(program.m_program_object_id, subroutine_names[inverse_order_routine_index], 300348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos subroutine_names[inverse_routine_index], subroutine_uniform_names, 300448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos inverse_order_inverse_data, true)) || 300548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos (false == testDraw(program.m_program_object_id, subroutine_names[inverse_order_routine_index], 300648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos subroutine_names[square_routine_index], subroutine_uniform_names, 300748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos inverse_order_square_data, true)) || 300848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos (false == testDraw(program.m_program_object_id, subroutine_names[negate_routine_index], 300948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos subroutine_names[inverse_routine_index], subroutine_uniform_names, negate_inverse_data, 301048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos true)) || 301148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos (false == testDraw(program.m_program_object_id, subroutine_names[negate_routine_index], 301248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos subroutine_names[square_routine_index], subroutine_uniform_names, negate_square_data, 301348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos true)) || 301448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos (false == testDraw(program.m_program_object_id, subroutine_names[inverse_routine_index], 301548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos subroutine_names[square_routine_index], subroutine_uniform_names, inverse_square_data, 301648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos true))) 301748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 301848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = false; 301948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 302048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 302148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 302248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Done */ 302348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (true == result) 302448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 302548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 302648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 302748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else 302848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 302948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 303048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 303148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 303248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return tcu::TestNode::STOP; 303348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 303448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 303548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Verify result of getProgramStageiv 303648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 303748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param program_id Program object id 303848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param pname <pname> parameter for getProgramStageiv 303948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param expected Expected value 304048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 304148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return true if result is equal to expected value, flase otherwise 304248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 304348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosbool FunctionalTest3_4::checkProgramStageiv(glw::GLuint program_id, glw::GLenum pname, glw::GLint expected) const 304448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 304548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 304648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLint value = 0; 304748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 304848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getProgramStageiv(program_id, GL_VERTEX_SHADER, pname, &value); 304948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramStageiv"); 305048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 305148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (expected != value) 305248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 305348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_context.getTestContext().getLog() << tcu::TestLog::Message 305448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << "Error. Invalid result. Function: getProgramStageiv. " 305548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << "pname: " << Utils::pnameToStr(pname) << ". " 305648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << "Result: " << value << ". " 305748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << "Expected: " << expected << "." << tcu::TestLog::EndMessage; 305848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 305948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return false; 306048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 306148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else 306248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 306348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return true; 306448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 306548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 306648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 306748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Verify result of getProgramResourceiv 306848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 306948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param program_id Program object id 307048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param program_interface Program interface 307148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param pname <pname> parameter for getProgramStageiv 307248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param resource_name Resource name 307348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param expected Expected value 307448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 307548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return true if result is equal to expected value, false otherwise 307648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 307748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosbool FunctionalTest3_4::checkProgramResourceiv(GLuint program_id, GLenum program_interface, GLenum pname, 307848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::GLchar* resource_name, GLint expected) const 307948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 308048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 308148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint index = gl.getProgramResourceIndex(program_id, program_interface, resource_name); 308248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLint value = 0; 308348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 308448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (GL_INVALID_INDEX == index) 308548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 308648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return false; 308748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 308848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 308948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getProgramResourceiv(program_id, program_interface, index, 1, &pname, 1, 0, &value); 309048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "getProgramResourceiv"); 309148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 309248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (expected != value) 309348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 309448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_context.getTestContext().getLog() 309548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << tcu::TestLog::Message << "Error. Invalid result. Function: getProgramResourceiv. " 309648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << "Program interface: " << Utils::programInterfaceToStr(program_interface) << ". " 309748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << "Resource name: " << resource_name << ". " 309848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << "Property: " << Utils::pnameToStr(pname) << ". " 309948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << "Result: " << value << ". " 310048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << "Expected: " << expected << "." << tcu::TestLog::EndMessage; 310148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 310248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return false; 310348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 310448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else 310548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 310648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return true; 310748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 310848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 310948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 311048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Verify result of getProgramInterfaceiv 311148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 311248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param program_id Program object id 311348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param program_interface Program interface 311448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param pname <pname> parameter for getProgramStageiv 311548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param expected Expected value 311648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 311748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return true if result is equal to expected value, flase otherwise 311848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 311948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosbool FunctionalTest3_4::checkProgramInterfaceiv(GLuint program_id, GLenum program_interface, GLenum pname, 312048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLint expected) const 312148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 312248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 312348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLint value = 0; 312448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 312548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getProgramInterfaceiv(program_id, program_interface, pname, &value); 312648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramInterfaceiv"); 312748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 312848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (expected != value) 312948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 313048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_context.getTestContext().getLog() 313148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << tcu::TestLog::Message << "Error. Invalid result. Function: getProgramInterfaceiv. " 313248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << "Program interface: " << Utils::programInterfaceToStr(program_interface) << ". " 313348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << "pname: " << Utils::pnameToStr(pname) << ". " 313448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << "Result: " << value << ". " 313548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << "Expected: " << expected << "." << tcu::TestLog::EndMessage; 313648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 313748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return false; 313848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 313948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else 314048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 314148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return true; 314248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 314348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 314448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 314548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Verify result of getActiveSubroutineUniformiv 314648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 314748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param program_id Program object id 314848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param index <index> parameter for getActiveSubroutineUniformiv 314948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param pname <pname> parameter for getActiveSubroutineUniformiv 315048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param expected Expected value 315148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 315248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return true if result is equal to expected value, flase otherwise 315348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 315448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosbool FunctionalTest3_4::checkActiveSubroutineUniformiv(GLuint program_id, GLuint index, GLenum pname, 315548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLint expected) const 315648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 315748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 315848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLint value = 0; 315948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 316048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getActiveSubroutineUniformiv(program_id, GL_VERTEX_SHADER, index, pname, &value); 316148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "getActiveSubroutineUniformiv"); 316248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 316348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (expected != value) 316448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 316548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_context.getTestContext().getLog() << tcu::TestLog::Message 316648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << "Error. Invalid result. Function: getActiveSubroutineUniformiv. " 316748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << "idnex: " << index << ". " 316848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << "pname: " << Utils::pnameToStr(pname) << ". " 316948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << "Result: " << value << ". " 317048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << "Expected: " << expected << "." << tcu::TestLog::EndMessage; 317148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 317248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return false; 317348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 317448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else 317548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 317648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return true; 317748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 317848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 317948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 318048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Returns index of program resource 318148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 318248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param program_id Program object id 318348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param program_interface Program interface 318448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param resource_name Name of resource 318548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 318648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return Index of specified resource 318748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 318848087f5f0eb08759ee763f98daf3b34becb74559Pyry HaulosGLuint FunctionalTest3_4::getProgramResourceIndex(GLuint program_id, GLenum program_interface, 318948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::GLchar* resource_name) const 319048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 319148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 319248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint index = gl.getProgramResourceIndex(program_id, program_interface, resource_name); 319348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 319448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "getProgramResourceIndex"); 319548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 319648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (GL_INVALID_INDEX == index) 319748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 319848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_context.getTestContext().getLog() << tcu::TestLog::Message << "Error. Program resource is not available. " 319948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << "Program interface: " << Utils::programInterfaceToStr(program_interface) 320048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << ". " 320148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << "Resource name: " << resource_name << "." << tcu::TestLog::EndMessage; 320248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 320348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 320448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return index; 320548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 320648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 320748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Get subroutine index 320848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 320948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param program_id Program object id 321048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param subroutine_name Subroutine name 321148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param use_program_query If true getProgramResourceIndex is used, otherwise getSubroutineIndex 321248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 321348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return Index of subroutine 321448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 321548087f5f0eb08759ee763f98daf3b34becb74559Pyry HaulosGLuint FunctionalTest3_4::getSubroutineIndex(GLuint program_id, const glw::GLchar* subroutine_name, 321648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos bool use_program_query) const 321748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 321848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 321948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint index = -1; 322048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 322148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (false == use_program_query) 322248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 322348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos index = gl.getSubroutineIndex(program_id, GL_VERTEX_SHADER, subroutine_name); 322448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "GetSubroutineIndex"); 322548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 322648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else 322748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 322848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos index = gl.getProgramResourceIndex(program_id, GL_VERTEX_SUBROUTINE, subroutine_name); 322948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramResourceIndex"); 323048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 323148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 323248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (GL_INVALID_INDEX == index) 323348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 323448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos TCU_FAIL("Subroutine is not available"); 323548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 323648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 323748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return index; 323848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 323948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 324048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Get subroutine uniform location 324148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 324248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param program_id Program object id 324348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param uniform_name Subroutine uniform name 324448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param use_program_query If true getProgramResourceLocation is used, otherwise getSubroutineUniformLocation 324548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 324648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return Location of subroutine uniform 324748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 324848087f5f0eb08759ee763f98daf3b34becb74559Pyry HaulosGLint FunctionalTest3_4::getSubroutineUniformLocation(GLuint program_id, const glw::GLchar* uniform_name, 324948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos bool use_program_query) const 325048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 325148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 325248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLint location = -1; 325348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 325448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (false == use_program_query) 325548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 325648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos location = gl.getSubroutineUniformLocation(program_id, GL_VERTEX_SHADER, uniform_name); 325748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "GetSubroutineUniformLocation"); 325848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 325948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else 326048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 326148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos location = gl.getProgramResourceLocation(program_id, GL_VERTEX_SUBROUTINE_UNIFORM, uniform_name); 326248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramResourceLocation"); 326348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 326448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 326548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (-1 == location) 326648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 326748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos TCU_FAIL("Subroutine uniform is not available"); 326848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 326948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 327048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return location; 327148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 327248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 327348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Test if getProgramStageiv results are as expected 327448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 327548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param program_id Program object id 327648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 327748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @result false in case of invalid result for any pname, true otherwise 327848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 327948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosbool FunctionalTest3_4::inspectProgramStageiv(glw::GLuint program_id) const 328048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 328148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos bool result = true; 328248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 328348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const inspectionDetails details[] = { 328448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { GL_ACTIVE_SUBROUTINE_UNIFORMS, m_n_active_subroutine_uniforms }, 328548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS, m_n_active_subroutine_uniform_locations }, 328648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { GL_ACTIVE_SUBROUTINES, m_n_active_subroutines }, 328748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { GL_ACTIVE_SUBROUTINE_UNIFORM_MAX_LENGTH, m_n_active_subroutine_uniform_name_length + 1 }, 328848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { GL_ACTIVE_SUBROUTINE_MAX_LENGTH, m_n_active_subroutine_name_length + 1 } 328948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos }; 329048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLuint n_details = sizeof(details) / sizeof(details[0]); 329148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 329248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLuint i = 0; i < n_details; ++i) 329348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 329448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (false == checkProgramStageiv(program_id, details[i].pname, details[i].expected_value)) 329548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 329648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = false; 329748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 329848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 329948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 330048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return result; 330148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 330248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 330348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Test if checkProgramInterfaceiv results are as expected 330448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 330548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param program_id Program object id 330648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 330748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @result false in case of invalid result for any pname, true otherwise 330848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 330948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosbool FunctionalTest3_4::inspectProgramInterfaceiv(glw::GLuint program_id) const 331048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 331148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos bool result = true; 331248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 331348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const inspectionDetailsForProgramInterface details[] = { 331448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { GL_VERTEX_SUBROUTINE_UNIFORM, GL_ACTIVE_RESOURCES, m_n_active_subroutine_uniforms }, 331548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { GL_VERTEX_SUBROUTINE_UNIFORM, GL_MAX_NAME_LENGTH, m_n_active_subroutine_uniform_name_length + 1 }, 331648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { GL_VERTEX_SUBROUTINE_UNIFORM, GL_MAX_NUM_COMPATIBLE_SUBROUTINES, m_n_active_subroutines }, 331748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { GL_VERTEX_SUBROUTINE, GL_ACTIVE_RESOURCES, m_n_active_subroutines }, 331848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { GL_VERTEX_SUBROUTINE, GL_MAX_NAME_LENGTH, m_n_active_subroutine_name_length + 1 } 331948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos }; 332048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLuint n_details = sizeof(details) / sizeof(details[0]); 332148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 332248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLuint i = 0; i < n_details; ++i) 332348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 332448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (false == checkProgramInterfaceiv(program_id, details[i].program_interface, details[i].pname, 332548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos details[i].expected_value)) 332648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 332748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = false; 332848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 332948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 333048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 333148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return result; 333248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 333348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 333448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Test if checkProgramResourceiv results are as expected 333548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 333648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param program_id Program object id 333748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param subroutine_names Array of subroutine names 333848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param uniform_names Array of uniform names 333948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 334048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @result false in case of invalid result for any pname, true otherwise 334148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 334248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosbool FunctionalTest3_4::inspectProgramResourceiv(GLuint program_id, const GLchar** subroutine_names, 334348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLchar** uniform_names) const 334448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 334548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 334648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos bool result = true; 334748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 334848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLint subroutine = 0; subroutine < m_n_active_subroutines; ++subroutine) 334948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 335048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLchar* subroutine_name = subroutine_names[subroutine]; 335148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLint length = (GLint)strlen(subroutine_name) + 1; 335248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 335348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (false == checkProgramResourceiv(program_id, GL_VERTEX_SUBROUTINE, GL_NAME_LENGTH, subroutine_name, length)) 335448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 335548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = false; 335648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 335748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 335848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 335948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos inspectionDetails details[] = { 336048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { GL_NAME_LENGTH, 0 }, 336148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { GL_ARRAY_SIZE, 1 }, 336248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { GL_NUM_COMPATIBLE_SUBROUTINES, m_n_active_subroutines }, 336348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { GL_LOCATION, 0 }, 336448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos }; 336548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLuint n_details = sizeof(details) / sizeof(details[0]); 336648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 336748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLint uniform = 0; uniform < m_n_active_subroutine_uniforms; ++uniform) 336848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 336948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLchar* uniform_name = uniform_names[uniform]; 337048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLint length = (GLint)strlen(uniform_name) + 1; 337148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLint location = getSubroutineUniformLocation(program_id, uniform_name, true); 337248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 337348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos details[0].expected_value = length; 337448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos details[3].expected_value = location; 337548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 337648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLuint i = 0; i < n_details; ++i) 337748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 337848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (false == checkProgramResourceiv(program_id, GL_VERTEX_SUBROUTINE_UNIFORM, details[i].pname, 337948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos uniform_name, details[i].expected_value)) 338048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 338148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = false; 338248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 338348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 338448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 338548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Check compatible subroutines */ 338648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint index = getProgramResourceIndex(program_id, GL_VERTEX_SUBROUTINE_UNIFORM, uniform_name); 338748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 338848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (GL_INVALID_INDEX != index) 338948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 339048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::vector<GLint> compatible_subroutines; 339148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLint index_sum = 0; 339248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLenum prop = GL_COMPATIBLE_SUBROUTINES; 339348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 339448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos compatible_subroutines.resize(m_n_active_subroutines); 339548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 339648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getProgramResourceiv(program_id, GL_VERTEX_SUBROUTINE_UNIFORM, index, 1, &prop, m_n_active_subroutines, 339748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 0, &compatible_subroutines[0]); 339848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 339948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramResourceiv"); 340048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 340148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Expected indices are 0, 1, 2, ... N */ 340248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLint i = 0; i < m_n_active_subroutines; ++i) 340348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 340448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos index_sum += compatible_subroutines[i]; 340548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 340648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 340748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Sum of E1, ..., EN = (E1 + EN) * N / 2 */ 340848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (((m_n_active_subroutines - 1) * m_n_active_subroutines) / 2 != index_sum) 340948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 341048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos tcu::MessageBuilder message = m_context.getTestContext().getLog() << tcu::TestLog::Message; 341148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 341248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos message << "Error. Invalid result. Function: getProgramResourceiv. " 341348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << "Program interface: GL_VERTEX_SUBROUTINE_UNIFORM. " 341448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << "Resource name: " << uniform_name << ". " 341548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << "Property: GL_COMPATIBLE_SUBROUTINES. " 341648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << "Results: "; 341748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 341848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLint i = 1; i < m_n_active_subroutines; ++i) 341948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 342048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos message << compatible_subroutines[i]; 342148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 342248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 342348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos message << tcu::TestLog::EndMessage; 342448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 342548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = false; 342648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 342748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 342848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 342948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 343048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return result; 343148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 343248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 343348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Test if getActiveSubroutineUniformiv results are as expected 343448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 343548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param program_id Program object id 343648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param uniform_names Array of subroutine uniform names available in program 343748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 343848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @result false in case of invalid result for any pname, true otherwise 343948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 344048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosbool FunctionalTest3_4::inspectActiveSubroutineUniformiv(GLuint program_id, const GLchar** uniform_names) const 344148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 344248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 344348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos bool result = true; 344448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLint n_active_subroutine_uniforms = 0; 344548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 344648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos inspectionDetails details[] = { 344748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { GL_NUM_COMPATIBLE_SUBROUTINES, m_n_active_subroutines }, 344848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { GL_UNIFORM_SIZE, m_n_active_subroutine_uniform_size }, 344948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { GL_UNIFORM_NAME_LENGTH, 0 }, 345048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos }; 345148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLuint n_details = sizeof(details) / sizeof(details[0]); 345248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 345348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Get amount of active subroutine uniforms */ 345448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getProgramStageiv(program_id, GL_VERTEX_SHADER, GL_ACTIVE_SUBROUTINE_UNIFORMS, &n_active_subroutine_uniforms); 345548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramStageiv"); 345648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 345748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLint uniform = 0; uniform < n_active_subroutine_uniforms; ++uniform) 345848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 345948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLint name_length = (GLint)strlen(uniform_names[uniform]); 346048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 346148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos details[2].expected_value = name_length + 1; 346248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 346348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Checks from "details" */ 346448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLuint i = 0; i < n_details; ++i) 346548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 346648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (false == 346748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos checkActiveSubroutineUniformiv(program_id, uniform, details[i].pname, details[i].expected_value)) 346848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 346948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = false; 347048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 347148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 347248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 347348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Check compatible subroutines */ 347448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::vector<GLint> compatible_subroutines; 347548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos compatible_subroutines.resize(m_n_active_subroutines); 347648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLint index_sum = 0; 347748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 347848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getActiveSubroutineUniformiv(program_id, GL_VERTEX_SHADER, uniform, GL_COMPATIBLE_SUBROUTINES, 347948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos &compatible_subroutines[0]); 348048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "getActiveSubroutineUniformiv"); 348148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 348248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Expected indices are 0, 1, 2, ... N */ 348348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLint i = 0; i < m_n_active_subroutines; ++i) 348448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 348548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos index_sum += compatible_subroutines[i]; 348648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 348748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 348848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Sum of E1, ..., EN = (E1 + EN) * N / 2 */ 348948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (((m_n_active_subroutines - 1) * m_n_active_subroutines) / 2 != index_sum) 349048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 349148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos tcu::MessageBuilder message = m_context.getTestContext().getLog() << tcu::TestLog::Message; 349248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 349348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos message << "Error. Invalid result. Function: getActiveSubroutineUniformiv. idnex: " << uniform 349448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << ". pname: " << Utils::pnameToStr(GL_COMPATIBLE_SUBROUTINES) << ". Results: "; 349548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 349648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLint i = 1; i < m_n_active_subroutines; ++i) 349748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 349848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos message << compatible_subroutines[i]; 349948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 350048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 350148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos message << tcu::TestLog::EndMessage; 350248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 350348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = false; 350448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 350548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 350648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 350748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return result; 350848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 350948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 351048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Test if getActiveSubroutineUniformName results are as expected 351148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 351248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param program_id Program object id 351348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param uniform_names Array of subroutine uniform names available in program 351448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 351548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @result false in case of invalid result, true otherwise 351648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 351748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosbool FunctionalTest3_4::inspectActiveSubroutineUniformName(GLuint program_id, const GLchar** uniform_names) const 351848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 351948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 352048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos bool result = true; 352148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLint n_active_subroutine_uniforms = 0; 352248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::vector<GLchar> active_uniform_name; 352348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 352448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getProgramStageiv(program_id, GL_VERTEX_SHADER, GL_ACTIVE_SUBROUTINE_UNIFORMS, &n_active_subroutine_uniforms); 352548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramStageiv"); 352648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 352748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos active_uniform_name.resize(m_n_active_subroutine_uniform_name_length + 1); 352848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 352948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLint uniform = 0; uniform < n_active_subroutine_uniforms; ++uniform) 353048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 353148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos bool is_name_ok = false; 353248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 353348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getActiveSubroutineUniformName(program_id, GL_VERTEX_SHADER, uniform, (GLsizei)active_uniform_name.size(), 353448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 0 /* length */, &active_uniform_name[0]); 353548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "GetActiveSubroutineUniformName"); 353648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 353748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLint name = 0; name < n_active_subroutine_uniforms; ++name) 353848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 353948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (0 == strcmp(uniform_names[name], &active_uniform_name[0])) 354048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 354148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos is_name_ok = true; 354248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 354348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 354448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 354548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 354648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (false == is_name_ok) 354748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 354848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_context.getTestContext().getLog() 354948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << tcu::TestLog::Message 355048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << "Error. Invalid result. Function: getActiveSubroutineUniformName. idnex: " << uniform 355148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << ". Result: " << &active_uniform_name[0] << tcu::TestLog::EndMessage; 355248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 355348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = false; 355448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 355548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 355648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 355748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 355848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return result; 355948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 356048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 356148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Test if getActiveSubroutineUniformName results are as expected 356248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 356348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param program_id Program object id 356448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param subroutine_names Array of subroutine names available in program 356548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 356648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @result false in case of invalid result, true otherwise 356748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 356848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosbool FunctionalTest3_4::inspectActiveSubroutineName(GLuint program_id, const GLchar** subroutine_names) const 356948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 357048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 357148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos bool result = true; 357248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLint n_active_subroutines = 0; 357348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::vector<GLchar> active_subroutine_name; 357448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 357548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getProgramStageiv(program_id, GL_VERTEX_SHADER, GL_ACTIVE_SUBROUTINES, &n_active_subroutines); 357648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramStageiv"); 357748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 357848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos active_subroutine_name.resize(m_n_active_subroutine_name_length + 1); 357948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 358048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLint uniform = 0; uniform < n_active_subroutines; ++uniform) 358148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 358248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos bool is_name_ok = false; 358348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 358448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getActiveSubroutineName(program_id, GL_VERTEX_SHADER, uniform, (GLsizei)active_subroutine_name.size(), 358548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 0 /* length */, &active_subroutine_name[0]); 358648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "getActiveSubroutineName"); 358748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 358848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLint name = 0; name < n_active_subroutines; ++name) 358948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 359048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (0 == strcmp(subroutine_names[name], &active_subroutine_name[0])) 359148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 359248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos is_name_ok = true; 359348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 359448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 359548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 359648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 359748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (false == is_name_ok) 359848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 359948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_context.getTestContext().getLog() 360048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << tcu::TestLog::Message 360148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << "Error. Invalid result. Function: getActiveSubroutineName. idnex: " << uniform 360248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << ". Result: " << &active_subroutine_name[0] << tcu::TestLog::EndMessage; 360348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 360448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = false; 360548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 360648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 360748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 360848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 360948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return result; 361048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 361148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 361248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Test if it is possible to "bind" all subroutines uniforms with all subroutines 361348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 361448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param program_id Program object id 361548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param subroutine_names Array of subroutine names available in program 361648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param uniform_names Array of subroutine uniform names available in program 361748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 361848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @result false in case of invalid result, true otherwise 361948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 362048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosbool FunctionalTest3_4::inspectSubroutineBinding(GLuint program_id, const GLchar** subroutine_names, 362148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLchar** uniform_names, bool use_program_query) const 362248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 362348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 362448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos bool result = true; 362548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLint n_active_subroutines = 0; 362648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLint n_active_subroutine_uniforms = 0; 362748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::vector<GLuint> subroutine_uniforms; 362848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint queried_subroutine_index = 0; 362948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 363048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getProgramStageiv(program_id, GL_VERTEX_SHADER, GL_ACTIVE_SUBROUTINES, &n_active_subroutines); 363148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramStageiv"); 363248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 363348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getProgramStageiv(program_id, GL_VERTEX_SHADER, GL_ACTIVE_SUBROUTINE_UNIFORMS, &n_active_subroutine_uniforms); 363448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramStageiv"); 363548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 363648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos subroutine_uniforms.resize(n_active_subroutine_uniforms); 363748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 363848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLint uniform = 0; uniform < n_active_subroutine_uniforms; ++uniform) 363948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 364048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint uniform_location = getSubroutineUniformLocation(program_id, uniform_names[uniform], use_program_query); 364148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 364248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLint routine = 0; routine < n_active_subroutines; ++routine) 364348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 364448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint routine_index = getSubroutineIndex(program_id, subroutine_names[routine], use_program_query); 364548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 364648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos subroutine_uniforms[uniform] = routine_index; 364748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 364848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.uniformSubroutinesuiv(GL_VERTEX_SHADER, n_active_subroutine_uniforms, &subroutine_uniforms[0]); 364948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "UniformSubroutinesuiv"); 365048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 365148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getUniformSubroutineuiv(GL_VERTEX_SHADER, uniform_location, &queried_subroutine_index); 365248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "GetUniformSubroutineuiv"); 365348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 365448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (queried_subroutine_index != routine_index) 365548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 365648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_context.getTestContext().getLog() 365748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << tcu::TestLog::Message << "Error. Invalid result. Function: gl.getUniformSubroutineuiv." 365848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << " Subroutine uniform: " << uniform << ", name: " << uniform_names[uniform] 365948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << ", location: " << uniform_location << ". Subroutine: " << routine 366048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << ", name: " << subroutine_names[routine] << ", index: " << routine_index 366148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << ". Result: " << queried_subroutine_index << tcu::TestLog::EndMessage; 366248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 366348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = false; 366448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 366548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 366648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 366748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 366848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return result; 366948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 367048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 367148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Execute draw call and verify results 367248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 367348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param program_id Program object id 367448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param first_routine_name Name of subroutine that shall be used aas first_routine 367548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param second_routine_name Name of subroutine that shall be used aas second_routine 367648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param uniform_names Name of uniforms 367748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param expected_results Test data. [0] is used as input data. All are used as expected_results 367848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param use_program_query If true GetProgram* API will be used 367948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 368048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return false in case of invalid result, true otherwise 368148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 368248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosbool FunctionalTest3_4::testDraw(GLuint program_id, const GLchar* first_routine_name, const GLchar* second_routine_name, 368348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLchar** uniform_names, const Utils::vec4<GLfloat> expected_results[5], 368448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos bool use_program_query) const 368548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 368648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLuint n_varyings = 5; 368748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 368848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos bool result = true; 368948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint subroutine_uniforms[2] = { 0 }; 369048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 369148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Get subroutine uniform locations */ 369248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLint first_routine_location = getSubroutineUniformLocation(program_id, uniform_names[0], use_program_query); 369348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 369448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLint second_routine_location = getSubroutineUniformLocation(program_id, uniform_names[1], use_program_query); 369548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 369648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Get subroutine indices */ 369748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint first_routine_index = getSubroutineIndex(program_id, first_routine_name, use_program_query); 369848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 369948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint second_routine_index = getSubroutineIndex(program_id, second_routine_name, use_program_query); 370048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 370148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Map uniforms with subroutines */ 370248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos subroutine_uniforms[first_routine_location] = first_routine_index; 370348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos subroutine_uniforms[second_routine_location] = second_routine_index; 370448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 370548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.uniformSubroutinesuiv(GL_VERTEX_SHADER, 2 /* number of uniforms */, &subroutine_uniforms[0]); 370648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "UniformSubroutinesuiv"); 370748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 370848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Get location of input_data */ 370948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLint input_data_location = gl.getUniformLocation(program_id, "input_data"); 371048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "GetUniformLocation"); 371148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 371248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (-1 == input_data_location) 371348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 371448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos TCU_FAIL("Uniform is not available"); 371548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 371648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 371748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Set up input_data */ 371848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.uniform4f(input_data_location, expected_results[0].m_x, expected_results[0].m_y, expected_results[0].m_z, 371948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos expected_results[0].m_w); 372048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "Uniform4f"); 372148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 372248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Execute draw call with transform feedback */ 372348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.beginTransformFeedback(GL_POINTS); 372448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback"); 372548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 372648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.drawArrays(GL_POINTS, 0 /* first */, 1 /* count */); 372748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays"); 372848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 372948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.endTransformFeedback(); 373048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback"); 373148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 373248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Verify results */ 373348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLfloat* feedback_data = (GLfloat*)gl.mapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY); 373448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "MapBuffer"); 373548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 373648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::vec4<GLfloat> results[5]; 373748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 373848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos results[0].m_x = feedback_data[0]; 373948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos results[0].m_y = feedback_data[1]; 374048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos results[0].m_z = feedback_data[2]; 374148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos results[0].m_w = feedback_data[3]; 374248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 374348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos results[1].m_x = feedback_data[4]; 374448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos results[1].m_y = feedback_data[5]; 374548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos results[1].m_z = feedback_data[6]; 374648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos results[1].m_w = feedback_data[7]; 374748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 374848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos results[2].m_x = feedback_data[8]; 374948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos results[2].m_y = feedback_data[9]; 375048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos results[2].m_z = feedback_data[10]; 375148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos results[2].m_w = feedback_data[11]; 375248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 375348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos results[3].m_x = feedback_data[12]; 375448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos results[3].m_y = feedback_data[13]; 375548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos results[3].m_z = feedback_data[14]; 375648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos results[3].m_w = feedback_data[15]; 375748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 375848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos results[4].m_x = feedback_data[16]; 375948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos results[4].m_y = feedback_data[17]; 376048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos results[4].m_z = feedback_data[18]; 376148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos results[4].m_w = feedback_data[19]; 376248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 376348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER); 376448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "UnmapBuffer"); 376548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 376648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLuint i = 0; i < n_varyings; ++i) 376748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 376848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = result && (results[i] == expected_results[i]); 376948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 377048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 377148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (false == result) 377248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 377348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_context.getTestContext().getLog() << tcu::TestLog::Message 377448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << "Error. Invalid result. First routine: " << first_routine_name 377548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << ". Second routine: " << second_routine_name << tcu::TestLog::EndMessage; 377648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 377748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos tcu::MessageBuilder message = m_context.getTestContext().getLog() << tcu::TestLog::Message; 377848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 377948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos message << "Results:"; 378048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 378148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLuint i = 0; i < n_varyings; ++i) 378248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 378348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos results[i].log(message); 378448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 378548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 378648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos message << tcu::TestLog::EndMessage; 378748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 378848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos message = m_context.getTestContext().getLog() << tcu::TestLog::Message; 378948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 379048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos message << "Expected:"; 379148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 379248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLuint i = 0; i < n_varyings; ++i) 379348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 379448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos expected_results[i].log(message); 379548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 379648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 379748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos message << tcu::TestLog::EndMessage; 379848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 379948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 380048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return result; 380148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 380248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 380348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Constructor 380448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 380548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param context CTS context 380648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 380748087f5f0eb08759ee763f98daf3b34becb74559Pyry HaulosFunctionalTest5::FunctionalTest5(deqp::Context& context) 380848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos : TestCase(context, "eight_subroutines_four_uniforms", "Verify multiple subroutine sets") 380948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 381048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 381148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 381248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Execute test 381348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 381448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return tcu::TestNode::STOP 381548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 381648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulostcu::TestNode::IterateResult FunctionalTest5::iterate() 381748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 381848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLchar* vertex_shader_code = 381948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "#version 400 core\n" 382048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "#extension GL_ARB_shader_subroutine : require\n" 382148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 382248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "precision highp float;\n" 382348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 382448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "// Subroutine types\n" 382548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine vec4 routine_type_1(in vec4 left, in vec4 right);\n" 382648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine vec4 routine_type_2(in vec4 iparam);\n" 382748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine vec4 routine_type_3(in vec4 a, in vec4 b, in vec4 c);\n" 382848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine bvec4 routine_type_4(in vec4 left, in vec4 right);\n" 382948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 383048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "// Subroutine definitions\n" 383148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "// 1st type\n" 383248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine(routine_type_1) vec4 add(in vec4 left, in vec4 right)\n" 383348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 383448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " return left + right;\n" 383548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 383648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 383748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine(routine_type_1) vec4 subtract(in vec4 left, in vec4 right)\n" 383848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 383948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " return left - right;\n" 384048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 384148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 384248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "// 2nd type\n" 384348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine(routine_type_2) vec4 square(in vec4 iparam)\n" 384448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 384548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " return iparam * iparam;\n" 384648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 384748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 384848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine(routine_type_2) vec4 square_root(in vec4 iparam)\n" 384948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 385048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " return sqrt(iparam);\n" 385148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 385248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 385348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "// 3rd type\n" 385448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine(routine_type_3) vec4 do_fma(in vec4 a, in vec4 b, in vec4 c)\n" 385548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 385648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " return fma(a, b, c);\n" 385748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 385848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 385948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine(routine_type_3) vec4 blend(in vec4 a, in vec4 b, in vec4 c)\n" 386048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 386148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " return c * a + (vec4(1) - c) * b;\n" 386248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 386348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 386448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "// 4th type\n" 386548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine(routine_type_4) bvec4 are_equal(in vec4 left, in vec4 right)\n" 386648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 386748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " return equal(left, right);\n" 386848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 386948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 387048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine(routine_type_4) bvec4 are_greater(in vec4 left, in vec4 right)\n" 387148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 387248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " return greaterThan(left, right);\n" 387348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 387448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 387548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "// Sub routine uniforms\n" 387648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine uniform routine_type_1 first_routine;\n" 387748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine uniform routine_type_2 second_routine;\n" 387848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine uniform routine_type_3 third_routine;\n" 387948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine uniform routine_type_4 fourth_routine;\n" 388048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 388148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "// Input data\n" 388248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "uniform vec4 first_input;\n" 388348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "uniform vec4 second_input;\n" 388448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "uniform vec4 third_input;\n" 388548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 388648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "// Output\n" 388748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "out vec4 out_result_from_first_routine;\n" 388848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "out vec4 out_result_from_second_routine;\n" 388948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "out vec4 out_result_from_third_routine;\n" 389048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "out uvec4 out_result_from_fourth_routine;\n" 389148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 389248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void main()\n" 389348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 389448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " out_result_from_first_routine = first_routine (first_input, second_input);\n" 389548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " out_result_from_second_routine = second_routine(first_input);\n" 389648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " out_result_from_third_routine = third_routine (first_input, second_input, third_input);\n" 389748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " out_result_from_fourth_routine = uvec4(fourth_routine(first_input, second_input));\n" 389848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 389948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n"; 390048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 390148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLchar* subroutine_names[4][2] = { 390248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { "add", "subtract" }, { "square", "square_root" }, { "do_fma", "blend" }, { "are_equal", "are_greater" } 390348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos }; 390448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 390548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLchar* subroutine_uniform_names[4][1] = { 390648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { "first_routine" }, { "second_routine" }, { "third_routine" }, { "fourth_routine" } 390748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos }; 390848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 390948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLuint n_subroutine_types = sizeof(subroutine_names) / sizeof(subroutine_names[0]); 391048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLuint n_subroutines_per_type = sizeof(subroutine_names[0]) / sizeof(subroutine_names[0][0]); 391148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLuint n_subroutine_uniforms_per_type = 391248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos sizeof(subroutine_uniform_names[0]) / sizeof(subroutine_uniform_names[0][0]); 391348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 391448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLchar* uniform_names[] = { "first_input", "second_input", "third_input" }; 391548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLuint n_uniform_names = sizeof(uniform_names) / sizeof(uniform_names[0]); 391648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 391748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLchar* varying_names[] = { "out_result_from_first_routine", "out_result_from_second_routine", 391848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "out_result_from_third_routine", "out_result_from_fourth_routine" }; 391948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLuint n_varyings = sizeof(varying_names) / sizeof(varying_names[0]); 392048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLuint transform_feedback_buffer_size = n_varyings * sizeof(GLfloat) * 4 /* vec4 */; 392148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 392248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Test data */ 392348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const Utils::vec4<GLfloat> input_data[3] = { Utils::vec4<GLfloat>(1.0f, 4.0f, 9.0f, 16.0f), 392448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::vec4<GLfloat>(16.0f, 9.0f, 4.0f, 1.0f), 392548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::vec4<GLfloat>(0.25f, 0.5f, 0.75f, 1.0f) }; 392648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 392748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const Utils::vec4<GLfloat> expected_result_from_first_routine[2] = { 392848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::vec4<GLfloat>(17.0f, 13.0f, 13.0f, 17.0f), Utils::vec4<GLfloat>(-15.0f, -5.0f, 5.0f, 15.0f) 392948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos }; 393048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 393148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const Utils::vec4<GLfloat> expected_result_from_second_routine[2] = { 393248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::vec4<GLfloat>(1.0f, 16.0f, 81.0f, 256.0f), Utils::vec4<GLfloat>(1.0f, 2.0f, 3.0f, 4.0f) 393348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos }; 393448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 393548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const Utils::vec4<GLfloat> expected_result_from_third_routine[2] = { 393648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::vec4<GLfloat>(16.25f, 36.5f, 36.75f, 17.0f), Utils::vec4<GLfloat>(12.25f, 6.5f, 7.75f, 16.0f) 393748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos }; 393848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 393948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const Utils::vec4<GLuint> expected_result_from_fourth_routine[2] = { Utils::vec4<GLuint>(0, 0, 0, 0), 394048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::vec4<GLuint>(0, 0, 1, 1) }; 394148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 394248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* All combinations of subroutines */ 394348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLuint subroutine_combinations[][4] = { 394448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 0, 0, 0, 0 }, { 0, 0, 0, 1 }, { 0, 0, 1, 0 }, { 0, 0, 1, 1 }, { 0, 1, 0, 0 }, { 0, 1, 0, 1 }, 394548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 0, 1, 1, 0 }, { 0, 1, 1, 1 }, { 1, 0, 0, 0 }, { 1, 0, 0, 1 }, { 1, 0, 1, 0 }, { 1, 0, 1, 1 }, 394648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1, 1, 0, 0 }, { 1, 1, 0, 1 }, { 1, 1, 1, 0 }, { 1, 1, 1, 1 } 394748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos }; 394848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLuint n_subroutine_combinations = 394948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos sizeof(subroutine_combinations) / sizeof(subroutine_combinations[0]); 395048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 395148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Do not execute the test if GL_ARB_shader_subroutine is not supported */ 395248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_shader_subroutine")) 395348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 395448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos throw tcu::NotSupportedError("GL_ARB_shader_subroutine is not supported."); 395548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 395648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 395748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Result */ 395848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos bool result = true; 395948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 396048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* GL objects */ 396148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::program program(m_context); 396248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::buffer transform_feedback_buffer(m_context); 396348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::vertexArray vao(m_context); 396448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 396548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Init GL objects */ 396648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos program.build(0 /* cs */, 0 /* fs */, 0 /* gs */, 0 /* tcs */, 0 /* test */, vertex_shader_code, varying_names, 396748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos n_varyings); 396848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 396948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos program.use(); 397048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 397148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos vao.generate(); 397248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos vao.bind(); 397348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 397448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos transform_feedback_buffer.generate(); 397548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos transform_feedback_buffer.update(GL_TRANSFORM_FEEDBACK_BUFFER, transform_feedback_buffer_size, 0 /* data */, 397648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GL_DYNAMIC_COPY); 397748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos transform_feedback_buffer.bindRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, 0, transform_feedback_buffer_size); 397848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 397948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Get subroutine uniform locations and subroutine indices */ 398048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLuint type = 0; type < n_subroutine_types; ++type) 398148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 398248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLuint uniform = 0; uniform < n_subroutine_uniforms_per_type; ++uniform) 398348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 398448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_subroutine_uniform_locations[type][uniform] = 398548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos program.getSubroutineUniformLocation(subroutine_uniform_names[type][uniform], GL_VERTEX_SHADER); 398648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 398748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 398848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLuint routine = 0; routine < n_subroutines_per_type; ++routine) 398948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 399048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_subroutine_indices[type][routine] = 399148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos program.getSubroutineIndex(subroutine_names[type][routine], GL_VERTEX_SHADER); 399248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 399348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 399448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 399548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Get uniform locations */ 399648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLuint i = 0; i < n_uniform_names; ++i) 399748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 399848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_uniform_locations[i] = program.getUniformLocation(uniform_names[i]); 399948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 400048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 400148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Draw with each routine combination */ 400248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLuint i = 0; i < n_subroutine_combinations; ++i) 400348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 400448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::vec4<GLfloat> first_routine_result; 400548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::vec4<GLfloat> second_routine_result; 400648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::vec4<GLfloat> third_routine_result; 400748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::vec4<GLuint> fourth_routine_result; 400848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 400948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos testDraw(subroutine_combinations[i], input_data, first_routine_result, second_routine_result, 401048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos third_routine_result, fourth_routine_result); 401148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 401248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (false == verify(first_routine_result, second_routine_result, third_routine_result, fourth_routine_result, 401348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos expected_result_from_first_routine[subroutine_combinations[i][0]], 401448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos expected_result_from_second_routine[subroutine_combinations[i][1]], 401548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos expected_result_from_third_routine[subroutine_combinations[i][2]], 401648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos expected_result_from_fourth_routine[subroutine_combinations[i][3]])) 401748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 401848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos logError(subroutine_names, subroutine_combinations[i], input_data, first_routine_result, 401948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos second_routine_result, third_routine_result, fourth_routine_result, 402048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos expected_result_from_first_routine[subroutine_combinations[i][0]], 402148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos expected_result_from_second_routine[subroutine_combinations[i][1]], 402248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos expected_result_from_third_routine[subroutine_combinations[i][2]], 402348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos expected_result_from_fourth_routine[subroutine_combinations[i][3]]); 402448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 402548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = false; 402648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 402748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 402848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 402948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Done */ 403048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (true == result) 403148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 403248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 403348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 403448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else 403548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 403648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 403748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 403848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 403948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return tcu::TestNode::STOP; 404048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 404148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 404248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Log error message 404348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 404448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param subroutine_names Array of subroutine names 404548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param subroutine_combination Combination of subroutines 404648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param input_data Input data 404748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param first_routine_result Result of first routine 404848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param second_routine_result Result of second routine 404948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param third_routine_result Result of third routine 405048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param fourth_routine_result Result of fourth routine 405148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param first_routine_expected_result Expected result of first routine 405248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param second_routine_expected_result Expected result of second routine 405348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param third_routine_expected_result Expected result of third routine 405448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param fourth_routine_expected_result Expected result of fourth routine 405548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 405648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid FunctionalTest5::logError(const glw::GLchar* subroutine_names[4][2], const glw::GLuint subroutine_combination[4], 405748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const Utils::vec4<glw::GLfloat> input_data[3], 405848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const Utils::vec4<glw::GLfloat>& first_routine_result, 405948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const Utils::vec4<glw::GLfloat>& second_routine_result, 406048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const Utils::vec4<glw::GLfloat>& third_routine_result, 406148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const Utils::vec4<glw::GLuint>& fourth_routine_result, 406248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const Utils::vec4<glw::GLfloat>& first_routine_expected_result, 406348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const Utils::vec4<glw::GLfloat>& second_routine_expected_result, 406448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const Utils::vec4<glw::GLfloat>& third_routine_expected_result, 406548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const Utils::vec4<glw::GLuint>& fourth_routine_expected_result) const 406648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 406748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_context.getTestContext().getLog() << tcu::TestLog::Message << "Error. Invalid result." 406848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << tcu::TestLog::EndMessage; 406948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 407048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos tcu::MessageBuilder message = m_context.getTestContext().getLog() << tcu::TestLog::Message; 407148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 407248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos message << "Function: " << subroutine_names[0][subroutine_combination[0]] << "( "; 407348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos input_data[0].log(message); 407448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos message << ", "; 407548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos input_data[1].log(message); 407648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos message << " ). Result: "; 407748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos first_routine_result.log(message); 407848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos message << ". Expected: "; 407948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos first_routine_expected_result.log(message); 408048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 408148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos message << tcu::TestLog::EndMessage; 408248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 408348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos message = m_context.getTestContext().getLog() << tcu::TestLog::Message; 408448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 408548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos message << "Function: " << subroutine_names[1][subroutine_combination[1]] << "( "; 408648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos input_data[0].log(message); 408748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos message << " ). Result: "; 408848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos second_routine_result.log(message); 408948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos message << ". Expected: "; 409048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos second_routine_expected_result.log(message); 409148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 409248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos message << tcu::TestLog::EndMessage; 409348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 409448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos message = m_context.getTestContext().getLog() << tcu::TestLog::Message; 409548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 409648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos message << "Function: " << subroutine_names[2][subroutine_combination[2]] << "( "; 409748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos input_data[0].log(message); 409848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos message << ", "; 409948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos input_data[1].log(message); 410048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos message << ", "; 410148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos input_data[2].log(message); 410248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos message << "). Result: "; 410348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos third_routine_result.log(message); 410448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos message << ". Expected: "; 410548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos third_routine_expected_result.log(message); 410648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 410748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos message << tcu::TestLog::EndMessage; 410848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 410948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos message = m_context.getTestContext().getLog() << tcu::TestLog::Message; 411048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 411148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos message << "Function: " << subroutine_names[3][subroutine_combination[3]] << "( "; 411248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos input_data[0].log(message); 411348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos message << ", "; 411448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos input_data[1].log(message); 411548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos message << ", "; 411648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos message << " ). Result: "; 411748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos fourth_routine_result.log(message); 411848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos message << ". Expected: "; 411948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos fourth_routine_expected_result.log(message); 412048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 412148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos message << tcu::TestLog::EndMessage; 412248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 412348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 412448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Execute draw call and capture results 412548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 412648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param subroutine_combination Combination of subroutines 412748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param input_data Input data 412848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param out_first_routine_result Result of first routine 412948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param out_second_routine_result Result of second routine 413048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param out_third_routine_result Result of third routine 413148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param out_fourth_routine_result Result of fourth routine 413248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 413348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid FunctionalTest5::testDraw(const glw::GLuint subroutine_combination[4], 413448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const Utils::vec4<glw::GLfloat> input_data[3], 413548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::vec4<glw::GLfloat>& out_first_routine_result, 413648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::vec4<glw::GLfloat>& out_second_routine_result, 413748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::vec4<glw::GLfloat>& out_third_routine_result, 413848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::vec4<glw::GLuint>& out_fourth_routine_result) const 413948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 414048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLuint n_uniforms = sizeof(m_uniform_locations) / sizeof(m_uniform_locations[0]); 414148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 414248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint subroutine_indices[4]; 414348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLuint n_subroutine_uniforms = sizeof(subroutine_indices) / sizeof(subroutine_indices[0]); 414448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 414548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Prepare subroutine uniform data */ 414648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLuint i = 0; i < n_subroutine_uniforms; ++i) 414748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 414848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLuint location = m_subroutine_uniform_locations[i][0]; 414948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 415048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos subroutine_indices[location] = m_subroutine_indices[i][subroutine_combination[i]]; 415148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 415248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 415348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Set up subroutine uniforms */ 415448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.uniformSubroutinesuiv(GL_VERTEX_SHADER, n_subroutine_uniforms, &subroutine_indices[0]); 415548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "UniformSubroutinesuiv"); 415648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 415748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Set up input data uniforms */ 415848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLuint i = 0; i < n_uniforms; ++i) 415948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 416048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.uniform4f(m_uniform_locations[i], input_data[i].m_x, input_data[i].m_y, input_data[i].m_z, 416148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos input_data[i].m_w); 416248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "Uniform4f"); 416348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 416448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 416548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Execute draw call with transform feedback */ 416648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.beginTransformFeedback(GL_POINTS); 416748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback"); 416848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 416948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.drawArrays(GL_POINTS, 0 /* first */, 1 /* count */); 417048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays"); 417148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 417248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.endTransformFeedback(); 417348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback"); 417448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 417548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Capture results */ 417648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLvoid* feedback_data = gl.mapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY); 417748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "MapBuffer"); 417848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 417948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLfloat* float_ptr = (GLfloat*)feedback_data; 418048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 418148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* First result */ 418248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos out_first_routine_result.m_x = float_ptr[0]; 418348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos out_first_routine_result.m_y = float_ptr[1]; 418448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos out_first_routine_result.m_z = float_ptr[2]; 418548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos out_first_routine_result.m_w = float_ptr[3]; 418648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 418748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Second result */ 418848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos out_second_routine_result.m_x = float_ptr[4]; 418948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos out_second_routine_result.m_y = float_ptr[5]; 419048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos out_second_routine_result.m_z = float_ptr[6]; 419148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos out_second_routine_result.m_w = float_ptr[7]; 419248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 419348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Third result */ 419448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos out_third_routine_result.m_x = float_ptr[8]; 419548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos out_third_routine_result.m_y = float_ptr[9]; 419648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos out_third_routine_result.m_z = float_ptr[10]; 419748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos out_third_routine_result.m_w = float_ptr[11]; 419848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 419948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Fourth result */ 420048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint* uint_ptr = (GLuint*)(float_ptr + 12); 420148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos out_fourth_routine_result.m_x = uint_ptr[0]; 420248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos out_fourth_routine_result.m_y = uint_ptr[1]; 420348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos out_fourth_routine_result.m_z = uint_ptr[2]; 420448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos out_fourth_routine_result.m_w = uint_ptr[3]; 420548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 420648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER); 420748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "UnmapBuffer"); 420848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 420948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 421048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Verify if results match expected results 421148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 421248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param first_routine_result Result of first routine 421348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param second_routine_result Result of second routine 421448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param third_routine_result Result of third routine 421548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param fourth_routine_result Result of fourth routine 421648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param first_routine_expected_result Expected result of first routine 421748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param second_routine_expected_result Expected result of second routine 421848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param third_routine_expected_result Expected result of third routine 421948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param fourth_routine_expected_result Expected result of fourth routine 422048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 422148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosbool FunctionalTest5::verify(const Utils::vec4<glw::GLfloat>& first_routine_result, 422248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const Utils::vec4<glw::GLfloat>& second_routine_result, 422348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const Utils::vec4<glw::GLfloat>& third_routine_result, 422448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const Utils::vec4<glw::GLuint>& fourth_routine_result, 422548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const Utils::vec4<glw::GLfloat>& first_routine_expected_result, 422648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const Utils::vec4<glw::GLfloat>& second_routine_expected_result, 422748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const Utils::vec4<glw::GLfloat>& third_routine_expected_result, 422848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const Utils::vec4<glw::GLuint>& fourth_routine_expected_result) const 422948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 423048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos bool result = true; 423148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 423248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = result && (first_routine_result == first_routine_expected_result); 423348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = result && (second_routine_result == second_routine_expected_result); 423448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = result && (third_routine_result == third_routine_expected_result); 423548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = result && (fourth_routine_result == fourth_routine_expected_result); 423648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 423748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return result; 423848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 423948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 424048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Constructor 424148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 424248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param context CTS context 424348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 424448087f5f0eb08759ee763f98daf3b34becb74559Pyry HaulosFunctionalTest6::FunctionalTest6(deqp::Context& context) 424548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos : TestCase(context, "static_subroutine_call", "Verify that subroutine can be called in a static manner") 424648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 424748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 424848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 424948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Execute test 425048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 425148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return tcu::TestNode::STOP 425248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 425348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulostcu::TestNode::IterateResult FunctionalTest6::iterate() 425448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 425548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLchar* vertex_shader_code = "#version 400 core\n" 425648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "#extension GL_ARB_shader_subroutine : require\n" 425748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 425848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "precision highp float;\n" 425948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 426048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "// Subroutine type\n" 426148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine vec4 routine_type(in vec4 iparam);\n" 426248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 426348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "// Subroutine definition\n" 426448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine(routine_type) vec4 square(in vec4 iparam)\n" 426548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 426648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " return iparam * iparam;\n" 426748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 426848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 426948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "// Sub routine uniform\n" 427048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine uniform routine_type routine;\n" 427148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 427248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "// Input data\n" 427348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "uniform vec4 input_data;\n" 427448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 427548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "// Output\n" 427648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "out vec4 out_result;\n" 427748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 427848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void main()\n" 427948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 428048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " out_result = square(input_data);\n" 428148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 428248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n"; 428348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 428448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLchar* varying_name = "out_result"; 428548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 428648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Test data */ 428748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const Utils::vec4<GLfloat> input_data(1.0f, 4.0f, 9.0f, 16.0f); 428848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 428948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const Utils::vec4<GLfloat> expected_result(1.0f, 16.0f, 81.0f, 256.0f); 429048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 429148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLuint transform_feedback_buffer_size = 4 * sizeof(GLfloat); 429248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 429348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Do not execute the test if GL_ARB_shader_subroutine is not supported */ 429448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_shader_subroutine")) 429548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 429648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos throw tcu::NotSupportedError("GL_ARB_shader_subroutine is not supported."); 429748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 429848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 429948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* GL objects */ 430048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::program program(m_context); 430148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::buffer transform_feedback_buffer(m_context); 430248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::vertexArray vao(m_context); 430348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 430448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Init GL objects */ 430548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos program.build(0 /* cs */, 0 /* fs */, 0 /* gs */, 0 /* tcs */, 0 /* test */, vertex_shader_code, &varying_name, 430648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1 /* n_varyings */); 430748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 430848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos program.use(); 430948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 431048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos vao.generate(); 431148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos vao.bind(); 431248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 431348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos transform_feedback_buffer.generate(); 431448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos transform_feedback_buffer.update(GL_TRANSFORM_FEEDBACK_BUFFER, transform_feedback_buffer_size, 0 /* data */, 431548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GL_DYNAMIC_COPY); 431648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos transform_feedback_buffer.bindRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, 0, transform_feedback_buffer_size); 431748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 431848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Test */ 431948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 432048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 432148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLint uniform_location = gl.getUniformLocation(program.m_program_object_id, "input_data"); 432248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 432348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "GetUniformLocation"); 432448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 432548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (-1 == uniform_location) 432648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 432748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos TCU_FAIL("Uniform is not available"); 432848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 432948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 433048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Set up input data uniforms */ 433148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.uniform4f(uniform_location, input_data.m_x, input_data.m_y, input_data.m_z, input_data.m_w); 433248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "Uniform4f"); 433348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 433448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Execute draw call with transform feedback */ 433548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.beginTransformFeedback(GL_POINTS); 433648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback"); 433748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 433848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.drawArrays(GL_POINTS, 0 /* first */, 1 /* count */); 433948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays"); 434048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 434148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.endTransformFeedback(); 434248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback"); 434348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 434448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Capture results */ 434548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLfloat* feedback_data = (GLfloat*)gl.mapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY); 434648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "MapBuffer"); 434748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 434848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::vec4<GLfloat> result(feedback_data[0], feedback_data[1], feedback_data[2], feedback_data[3]); 434948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 435048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER); 435148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "UnmapBuffer"); 435248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 435348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Verify */ 435448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (expected_result == result) 435548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 435648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 435748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 435848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else 435948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 436048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_context.getTestContext().getLog() << tcu::TestLog::Message << "Error. Invalid result." 436148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << tcu::TestLog::EndMessage; 436248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 436348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos tcu::MessageBuilder message = m_context.getTestContext().getLog() << tcu::TestLog::Message; 436448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 436548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos message << "Function: square( "; 436648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos input_data.log(message); 436748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos message << " ). Result: "; 436848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result.log(message); 436948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos message << ". Expected: "; 437048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos expected_result.log(message); 437148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 437248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos message << tcu::TestLog::EndMessage; 437348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 437448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 437548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 437648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 437748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 437848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Done */ 437948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return tcu::TestNode::STOP; 438048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 438148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 438248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Constructor 438348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 438448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param context CTS context 438548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 438648087f5f0eb08759ee763f98daf3b34becb74559Pyry HaulosFunctionalTest7_8::FunctionalTest7_8(deqp::Context& context) 438748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos : TestCase(context, "arrayed_subroutine_uniforms", "Verify that subroutine can be called in a static manner") 438848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 438948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 439048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 439148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Execute test 439248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 439348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return tcu::TestNode::STOP 439448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 439548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulostcu::TestNode::IterateResult FunctionalTest7_8::iterate() 439648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 439748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLchar* vertex_shader_code = 439848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "#version 400 core\n" 439948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "#extension GL_ARB_shader_subroutine : require\n" 440048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 440148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "precision highp float;\n" 440248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 440348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "// Subroutine type\n" 440448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine vec4 routine_type(in vec4 left, in vec4 right);\n" 440548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 440648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "// Subroutine definitions\n" 440748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine(routine_type) vec4 add(in vec4 left, in vec4 right)\n" 440848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 440948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " return left + right;\n" 441048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 441148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 441248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine(routine_type) vec4 multiply(in vec4 left, in vec4 right)\n" 441348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 441448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " return left * right;\n" 441548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 441648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 441748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "// Sub routine uniform\n" 441848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine uniform routine_type routine[4];\n" 441948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 442048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "// Input data\n" 442148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "uniform vec4 uni_left;\n" 442248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "uniform vec4 uni_right;\n" 442348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "uniform uvec4 uni_indices;\n" 442448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 442548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "// Output\n" 442648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "out vec4 out_combined;\n" 442748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "out vec4 out_combined_inverted;\n" 442848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "out vec4 out_constant;\n" 442948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "out vec4 out_constant_inverted;\n" 443048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "out vec4 out_dynamic;\n" 443148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "out vec4 out_dynamic_inverted;\n" 443248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "out vec4 out_loop;\n" 443348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "out uint out_array_length;\n" 443448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 443548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void main()\n" 443648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 443748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " out_combined = routine[3](routine[2](routine[1](routine[0](uni_left, uni_right), uni_right), " 443848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "uni_right), uni_right);\n" 443948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " out_combined_inverted = routine[0](routine[1](routine[2](routine[3](uni_left, uni_right), uni_right), " 444048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "uni_right), uni_right);\n" 444148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " \n" 444248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " out_constant = routine[3](routine[2](routine[1](routine[0](vec4(1, 2, 3, 4), vec4(-5, -6, -7, " 444348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "-8)), vec4(-1, -2, -3, -4)), vec4(5, 6, 7, 8)), vec4(1, 2, 3, 4));\n" 444448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " out_constant_inverted = routine[0](routine[1](routine[2](routine[3](vec4(1, 2, 3, 4), vec4(-5, -6, -7, " 444548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "-8)), vec4(-1, -2, -3, -4)), vec4(5, 6, 7, 8)), vec4(1, 2, 3, 4));\n" 444648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " \n" 444748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " out_dynamic = " 444848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "routine[uni_indices.w](routine[uni_indices.z](routine[uni_indices.y](routine[uni_indices.x](uni_left, " 444948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "uni_right), uni_right), uni_right), uni_right);\n" 445048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " out_dynamic_inverted = " 445148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "routine[uni_indices.x](routine[uni_indices.y](routine[uni_indices.z](routine[uni_indices.w](uni_left, " 445248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "uni_right), uni_right), uni_right), uni_right);\n" 445348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " \n" 445448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " out_loop = uni_left;\n" 445548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " for (uint i = 0u; i < routine.length(); ++i)\n" 445648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " {\n" 445748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " out_loop = routine[i](out_loop, uni_right);\n" 445848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " }\n" 445948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " \n" 446048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " out_array_length = routine.length() + 6 - (uni_indices.x + uni_indices.y + uni_indices.z + " 446148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "uni_indices.w);\n" 446248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 446348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n"; 446448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 446548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLchar* subroutine_names[] = { 446648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "add", "multiply", 446748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos }; 446848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLuint n_subroutine_names = sizeof(subroutine_names) / sizeof(subroutine_names[0]); 446948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 447048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLchar* subroutine_uniform_names[] = { "routine[0]", "routine[1]", "routine[2]", "routine[3]" }; 447148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLuint n_subroutine_uniform_names = 447248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos sizeof(subroutine_uniform_names) / sizeof(subroutine_uniform_names[0]); 447348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 447448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLchar* uniform_names[] = { 447548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "uni_left", "uni_right", "uni_indices", 447648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos }; 447748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLuint n_uniform_names = sizeof(uniform_names) / sizeof(uniform_names[0]); 447848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 447948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLchar* varying_names[] = { "out_combined", "out_combined_inverted", 448048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "out_constant", "out_constant_inverted", 448148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "out_dynamic", "out_dynamic_inverted", 448248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "out_loop", "out_array_length" }; 448348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 448448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLuint n_varyings = sizeof(varying_names) / sizeof(varying_names[0]); 448548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLuint transform_feedback_buffer_size = n_varyings * 4 * sizeof(GLfloat); 448648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 448748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Test data */ 448848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const Utils::vec4<GLfloat> uni_left(-1.0f, 0.75f, -0.5f, 0.25f); 448948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const Utils::vec4<GLfloat> uni_right(1.0f, -0.75f, 0.5f, -0.25f); 449048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const Utils::vec4<GLuint> uni_indices(1, 2, 0, 3); 449148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 449248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLuint subroutine_combinations[][4] = { 449348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 0, 0, 0, 0 }, /* + + + + */ 449448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 0, 0, 0, 1 }, /* + + + * */ 449548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 0, 0, 1, 0 }, /* + + * + */ 449648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 0, 0, 1, 1 }, /* + + * * */ 449748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 0, 1, 0, 0 }, /* + * + + */ 449848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 0, 1, 0, 1 }, /* + * + * */ 449948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 0, 1, 1, 0 }, /* + * * + */ 450048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 0, 1, 1, 1 }, /* + * * * */ 450148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1, 0, 0, 0 }, /* * + + + */ 450248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1, 0, 0, 1 }, /* * + + * */ 450348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1, 0, 1, 0 }, /* * + * + */ 450448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1, 0, 1, 1 }, /* * + * * */ 450548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1, 1, 0, 0 }, /* * * + + */ 450648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1, 1, 0, 1 }, /* * * + * */ 450748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1, 1, 1, 0 }, /* * * * + */ 450848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1, 1, 1, 1 } /* * * * * */ 450948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos }; 451048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLuint n_subroutine_combinations = 451148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos sizeof(subroutine_combinations) / sizeof(subroutine_combinations[0]); 451248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 451348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Do not execute the test if GL_ARB_shader_subroutine is not supported */ 451448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_shader_subroutine")) 451548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 451648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos throw tcu::NotSupportedError("GL_ARB_shader_subroutine is not supported."); 451748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 451848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 451948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* GL objects */ 452048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::program program(m_context); 452148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::buffer transform_feedback_buffer(m_context); 452248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::vertexArray vao(m_context); 452348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 452448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos bool result = true; 452548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 452648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Init GL objects */ 452748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos program.build(0 /* cs */, 0 /* fs */, 0 /* gs */, 0 /* tcs */, 0 /* test */, vertex_shader_code, varying_names, 452848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos n_varyings); 452948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 453048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos program.use(); 453148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 453248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos vao.generate(); 453348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos vao.bind(); 453448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 453548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos transform_feedback_buffer.generate(); 453648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 453748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Get subroutine indices */ 453848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLuint routine = 0; routine < n_subroutine_names; ++routine) 453948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 454048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_subroutine_indices[routine] = program.getSubroutineIndex(subroutine_names[routine], GL_VERTEX_SHADER); 454148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 454248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 454348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Get subroutine uniform locations */ 454448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLuint uniform = 0; uniform < n_subroutine_uniform_names; ++uniform) 454548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 454648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_subroutine_uniform_locations[uniform] = 454748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos program.getSubroutineUniformLocation(subroutine_uniform_names[uniform], GL_VERTEX_SHADER); 454848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 454948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 455048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Get uniform locations */ 455148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLuint i = 0; i < n_uniform_names; ++i) 455248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 455348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_uniform_locations[i] = program.getUniformLocation(uniform_names[i]); 455448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 455548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 455648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Test */ 455748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLuint i = 0; i < n_subroutine_combinations; ++i) 455848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 455948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Clean */ 456048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos transform_feedback_buffer.update(GL_TRANSFORM_FEEDBACK_BUFFER, transform_feedback_buffer_size, 0 /* data */, 456148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GL_DYNAMIC_COPY); 456248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos transform_feedback_buffer.bindRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, 0, transform_feedback_buffer_size); 456348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 456448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Verify */ 456548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (false == testDraw(subroutine_combinations[i], uni_left, uni_right, uni_indices)) 456648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 456748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = false; 456848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 456948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 457048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 457148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (true == result) 457248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 457348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 457448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 457548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else 457648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 457748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 457848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 457948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 458048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Done */ 458148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return tcu::TestNode::STOP; 458248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 458348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 458448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/* Calculate result of function applied to operands 458548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 458648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param function Function id, 0 is sum, 1 is multiplication 458748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param left Left operand 458848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param right Right operand 458948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param out Function result 459048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 459148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid FunctionalTest7_8::calculate(glw::GLuint function, const Utils::vec4<glw::GLfloat>& left, 459248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const Utils::vec4<glw::GLfloat>& right, Utils::vec4<glw::GLfloat>& out) const 459348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 459448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (0 == function) 459548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 459648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos out.m_x = left.m_x + right.m_x; 459748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos out.m_y = left.m_y + right.m_y; 459848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos out.m_z = left.m_z + right.m_z; 459948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos out.m_w = left.m_w + right.m_w; 460048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 460148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else 460248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 460348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos out.m_x = left.m_x * right.m_x; 460448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos out.m_y = left.m_y * right.m_y; 460548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos out.m_z = left.m_z * right.m_z; 460648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos out.m_w = left.m_w * right.m_w; 460748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 460848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 460948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 461048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Calculate expected values for all operations 461148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 461248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param combination Function combination, first applied function is at index [0] 461348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param left Left operand 461448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param right Right operand 461548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param indices Indices used by dynamic calls 461648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param out_combined Expected result of "combined" operation 461748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param out_combined_inverted Expected result of "combined_inverted" operation 461848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param out_constant Expected result of "constant" operation 461948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param out_constant_inverted Expected result of "constant_inverted" operation 462048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param out_dynamic Expected result of "dynamic" operation 462148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param out_dynamic_inverted Expected result of "out_dynamic_inverted" operation 462248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param out_loop Expected result of "loop" operation 462348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 462448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid FunctionalTest7_8::calculate( 462548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::GLuint combination[4], const Utils::vec4<glw::GLfloat>& left, const Utils::vec4<glw::GLfloat>& right, 462648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const Utils::vec4<glw::GLuint>& indices, Utils::vec4<glw::GLfloat>& out_combined, 462748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::vec4<glw::GLfloat>& out_combined_inverted, Utils::vec4<glw::GLfloat>& out_constant, 462848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::vec4<glw::GLfloat>& out_constant_inverted, Utils::vec4<glw::GLfloat>& out_dynamic, 462948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::vec4<glw::GLfloat>& out_dynamic_inverted, Utils::vec4<glw::GLfloat>& out_loop) const 463048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 463148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Indices used by "dynamic" operations, range <0..4> */ 463248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLuint dynamic_combination[4] = { combination[indices.m_x], combination[indices.m_y], 463348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos combination[indices.m_z], combination[indices.m_w] }; 463448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 463548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Values used by "constant" operations, come from shader code */ 463648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const Utils::vec4<glw::GLfloat> constant_values[] = { Utils::vec4<glw::GLfloat>(1, 2, 3, 4), 463748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::vec4<glw::GLfloat>(-5, -6, -7, -8), 463848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::vec4<glw::GLfloat>(-1, -2, -3, -4), 463948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::vec4<glw::GLfloat>(5, 6, 7, 8), 464048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::vec4<glw::GLfloat>(1, 2, 3, 4) }; 464148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 464248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Start values */ 464348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::vec4<glw::GLfloat> combined = left; 464448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::vec4<glw::GLfloat> combined_inverted = left; 464548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::vec4<glw::GLfloat> constant = constant_values[0]; 464648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::vec4<glw::GLfloat> constant_inverted = constant_values[0]; 464748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::vec4<glw::GLfloat> dynamic = left; 464848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::vec4<glw::GLfloat> dynamic_inverted = left; 464948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 465048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Calculate expected results */ 465148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLuint i = 0; i < 4; ++i) 465248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 465348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint function = combination[i]; 465448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint function_inverted = combination[3 - i]; 465548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint dynamic_function = dynamic_combination[i]; 465648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint dynamic_function_inverted = dynamic_combination[3 - i]; 465748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 465848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos calculate(function, combined, right, combined); 465948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos calculate(function_inverted, combined_inverted, right, combined_inverted); 466048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos calculate(function, constant, constant_values[i + 1], constant); 466148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos calculate(function_inverted, constant_inverted, constant_values[i + 1], constant_inverted); 466248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos calculate(dynamic_function, dynamic, right, dynamic); 466348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos calculate(dynamic_function_inverted, dynamic_inverted, right, dynamic_inverted); 466448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 466548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 466648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Store results */ 466748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos out_combined = combined; 466848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos out_combined_inverted = combined_inverted; 466948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos out_constant = constant; 467048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos out_constant_inverted = constant_inverted; 467148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos out_dynamic = dynamic; 467248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos out_dynamic_inverted = dynamic_inverted; 467348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos out_loop = combined; 467448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 467548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 467648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Log error 467748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 467848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param combination Operations combination 467948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param left Left operand 468048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param right Right operand 468148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param indices Inidices used by "dynamic" calls 468248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param vec4_expected Expected results 468348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param vec4_result Results 468448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param array_length Length of array 468548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param result Comparison results 468648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 468748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid FunctionalTest7_8::logError(const glw::GLuint combination[4], const Utils::vec4<glw::GLfloat>& left, 468848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const Utils::vec4<glw::GLfloat>& right, const Utils::vec4<glw::GLuint>& indices, 468948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const Utils::vec4<glw::GLfloat> vec4_expected[7], 469048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const Utils::vec4<glw::GLfloat> vec4_result[7], glw::GLuint array_length, 469148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos bool result[7]) const 469248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 469348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLuint n_functions = 4; 469448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLuint n_operations = 7; 469548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 469648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Indices used by "dynamic" operations, range <0..4> */ 469748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLuint dynamic_combination[4] = { combination[indices.m_x], combination[indices.m_y], 469848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos combination[indices.m_z], combination[indices.m_w] }; 469948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 470048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Function symbols */ 470148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLchar functions[4]; 470248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLchar functions_inverted[4]; 470348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLchar functions_dynamic[4]; 470448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLchar functions_dynamic_inverted[4]; 470548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 470648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLuint i = 0; i < n_functions; ++i) 470748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 470848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLchar function = (0 == combination[i]) ? '+' : '*'; 470948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLchar dynamic_function = (0 == dynamic_combination[i]) ? '+' : '*'; 471048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 471148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos functions[i] = function; 471248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos functions_inverted[n_functions - i - 1] = function; 471348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos functions_dynamic[i] = dynamic_function; 471448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos functions_dynamic_inverted[n_functions - i - 1] = dynamic_function; 471548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 471648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 471748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Values used by "constant" operations, come from shader code */ 471848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const Utils::vec4<glw::GLfloat> constant_values[] = { Utils::vec4<glw::GLfloat>(1, 2, 3, 4), 471948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::vec4<glw::GLfloat>(-5, -6, -7, -8), 472048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::vec4<glw::GLfloat>(-1, -2, -3, -4), 472148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::vec4<glw::GLfloat>(5, 6, 7, 8), 472248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::vec4<glw::GLfloat>(1, 2, 3, 4) }; 472348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 472448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Values used by non-"constant" operations */ 472548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::vec4<glw::GLfloat> dynamic_values[5]; 472648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos dynamic_values[0] = left; 472748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos dynamic_values[1] = right; 472848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos dynamic_values[2] = right; 472948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos dynamic_values[3] = right; 473048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos dynamic_values[4] = right; 473148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 473248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* For each operation */ 473348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLuint i = 0; i < n_operations; ++i) 473448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 473548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* If result is failure */ 473648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (false == result[i]) 473748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 473848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLchar* description = 0; 473948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const Utils::vec4<glw::GLfloat>* input = 0; 474048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLchar* operation = 0; 474148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 474248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos switch (i) 474348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 474448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case 0: 474548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos description = "Call made with predefined array indices"; 474648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos input = dynamic_values; 474748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos operation = functions; 474848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 474948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case 1: 475048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos description = "Call made with predefined array indices in inverted order"; 475148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos input = dynamic_values; 475248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos operation = functions_inverted; 475348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 475448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case 2: 475548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos description = "Call made with predefined array indices, for constant values"; 475648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos input = constant_values; 475748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos operation = functions; 475848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 475948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case 3: 476048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos description = "Call made with predefined array indices in inverted order, for constant values"; 476148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos input = constant_values; 476248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos operation = functions_inverted; 476348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 476448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case 4: 476548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos description = "Call made with dynamic array indices"; 476648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos input = dynamic_values; 476748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos operation = functions_dynamic; 476848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 476948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case 5: 477048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos description = "Call made with dynamic array indices in inverted order"; 477148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos input = dynamic_values; 477248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos operation = functions_dynamic_inverted; 477348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 477448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case 6: 477548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos description = "Call made with loop"; 477648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos input = dynamic_values; 477748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos operation = functions; 477848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 477948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 478048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 478148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_context.getTestContext().getLog() << tcu::TestLog::Message << "Error. Invalid result." 478248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << tcu::TestLog::EndMessage; 478348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 478448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_context.getTestContext().getLog() << tcu::TestLog::Message << description << tcu::TestLog::EndMessage; 478548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 478648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos tcu::MessageBuilder message = m_context.getTestContext().getLog() << tcu::TestLog::Message; 478748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 478848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos message << "Operation: (((("; 478948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos input[0].log(message); 479048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLuint function = 0; function < n_functions; ++function) 479148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 479248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos message << " " << operation[function] << " "; 479348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 479448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos input[function + 1].log(message); 479548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 479648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos message << ")"; 479748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 479848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 479948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos message << tcu::TestLog::EndMessage; 480048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 480148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos message = m_context.getTestContext().getLog() << tcu::TestLog::Message; 480248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 480348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos message << "Result: "; 480448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos vec4_result[i].log(message); 480548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 480648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos message << tcu::TestLog::EndMessage; 480748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 480848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos message = m_context.getTestContext().getLog() << tcu::TestLog::Message; 480948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 481048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos message << "Expected: "; 481148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos vec4_expected[i].log(message); 481248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 481348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos message << tcu::TestLog::EndMessage; 481448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 481548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 481648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Check array length, it should be 4 */ 481748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (4 != array_length) 481848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 481948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_context.getTestContext().getLog() << tcu::TestLog::Message 482048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << "Error. Invalid array length: " << array_length << ". Expected 4." 482148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << tcu::TestLog::EndMessage; 482248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 482348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 482448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 482548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 482648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Execute draw call and verifies captrued varyings 482748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 482848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param combination Function combination, first applied function is at index [0] 482948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param left Left operand 483048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param right Right operand 483148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param indices Indices used by dynamic calls 483248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 483348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return true if all results match expected values, false otherwise 483448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 483548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosbool FunctionalTest7_8::testDraw(const glw::GLuint combination[4], const Utils::vec4<glw::GLfloat>& left, 483648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const Utils::vec4<glw::GLfloat>& right, const Utils::vec4<glw::GLuint>& indices) const 483748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 483848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 483948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLuint n_vec4_varyings = 7; 484048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos bool result = true; 484148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint subroutine_indices[4]; 484248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLuint n_subroutine_uniforms = sizeof(subroutine_indices) / sizeof(subroutine_indices[0]); 484348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 484448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Prepare expected results */ 484548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::vec4<glw::GLfloat> expected_results[7]; 484648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos calculate(combination, left, right, indices, expected_results[0], expected_results[1], expected_results[2], 484748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos expected_results[3], expected_results[4], expected_results[5], expected_results[6]); 484848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 484948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Set up input data uniforms */ 485048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.uniform4f(m_uniform_locations[0], left.m_x, left.m_y, left.m_z, left.m_w); 485148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "Uniform4f"); 485248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 485348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.uniform4f(m_uniform_locations[1], right.m_x, right.m_y, right.m_z, right.m_w); 485448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "Uniform4f"); 485548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 485648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.uniform4ui(m_uniform_locations[2], indices.m_x, indices.m_y, indices.m_z, indices.m_w); 485748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "Uniform4ui"); 485848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 485948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Prepare subroutine uniform data */ 486048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLuint i = 0; i < n_subroutine_uniforms; ++i) 486148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 486248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLuint location = m_subroutine_uniform_locations[i]; 486348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 486448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos subroutine_indices[location] = m_subroutine_indices[combination[i]]; 486548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 486648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 486748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Set up subroutine uniforms */ 486848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.uniformSubroutinesuiv(GL_VERTEX_SHADER, n_subroutine_uniforms, &subroutine_indices[0]); 486948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "UniformSubroutinesuiv"); 487048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 487148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Execute draw call with transform feedback */ 487248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.beginTransformFeedback(GL_POINTS); 487348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback"); 487448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 487548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.drawArrays(GL_POINTS, 0 /* first */, 1 /* count */); 487648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays"); 487748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 487848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.endTransformFeedback(); 487948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback"); 488048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 488148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Capture results */ 488248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLvoid* feedback_data = (GLvoid*)gl.mapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY); 488348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "MapBuffer"); 488448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 488548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::vec4<GLfloat> vec4_results[7]; 488648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos bool results[7]; 488748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLfloat* float_data = (GLfloat*)feedback_data; 488848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLuint i = 0; i < n_vec4_varyings; ++i) 488948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 489048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos vec4_results[i].m_x = float_data[i * 4 + 0]; 489148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos vec4_results[i].m_y = float_data[i * 4 + 1]; 489248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos vec4_results[i].m_z = float_data[i * 4 + 2]; 489348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos vec4_results[i].m_w = float_data[i * 4 + 3]; 489448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 489548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 489648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint* uint_data = (GLuint*)(float_data + (n_vec4_varyings)*4); 489748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint array_length = uint_data[0]; 489848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 489948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Unmap buffer */ 490048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER); 490148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "UnmapBuffer"); 490248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 490348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Verification */ 490448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLuint i = 0; i < n_vec4_varyings; ++i) 490548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 490648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos results[i] = (vec4_results[i] == expected_results[i]); 490748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = result && results[i]; 490848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 490948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 491048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = result && (4 == array_length); 491148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 491248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Log error if any */ 491348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (false == result) 491448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 491548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos logError(combination, left, right, indices, expected_results, vec4_results, array_length, results); 491648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 491748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 491848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Done */ 491948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return result; 492048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 492148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 492248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Constructor. 492348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 492448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param context Rendering context. 492548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 492648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 492748087f5f0eb08759ee763f98daf3b34becb74559Pyry HaulosFunctionalTest9::FunctionalTest9(deqp::Context& context) 492848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos : TestCase(context, "subroutines_3_subroutine_types_and_subroutine_uniforms_one_function", 492948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "Makes sure that program with one function associated with 3 different " 493048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine types and 3 subroutine uniforms using that function compiles " 493148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "and works as expected") 493248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_has_test_passed(true) 493348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_n_points_to_draw(16) /* arbitrary value */ 493448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_po_id(0) 493548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_vao_id(0) 493648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_vs_id(0) 493748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_xfb_bo_id(0) 493848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 493948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Left blank intentionally */ 494048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 494148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 494248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** De-initializes GL objects that may have been created during test execution. */ 494348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid FunctionalTest9::deinit() 494448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 494548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 494648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 494748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_po_id != 0) 494848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 494948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteProgram(m_po_id); 495048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 495148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_po_id = 0; 495248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 495348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 495448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_vao_id != 0) 495548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 495648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteVertexArrays(1, &m_vao_id); 495748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 495848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_vao_id = 0; 495948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 496048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 496148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_vs_id != 0) 496248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 496348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteShader(m_vs_id); 496448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 496548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_vs_id = 0; 496648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 496748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 496848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_xfb_bo_id != 0) 496948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 497048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteBuffers(1, &m_xfb_bo_id); 497148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 497248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_xfb_bo_id = 0; 497348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 497448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 497548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 497648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Retrieves body of a vertex shader that should be used 497748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * for the testing purposes. 497848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 497948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosstd::string FunctionalTest9::getVertexShaderBody() const 498048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 498148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return "#version 400\n" 498248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 498348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "#extension GL_ARB_shader_subroutine : require\n" 498448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 498548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine void subroutineType1(inout float);\n" 498648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine void subroutineType2(inout float);\n" 498748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine void subroutineType3(inout float);\n" 498848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 498948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine(subroutineType1, subroutineType2, subroutineType3) void function(inout float result)\n" 499048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 499148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " result += float(0.123) + float(gl_VertexID);\n" 499248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 499348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 499448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine uniform subroutineType1 subroutine_uniform1;\n" 499548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine uniform subroutineType2 subroutine_uniform2;\n" 499648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine uniform subroutineType3 subroutine_uniform3;\n" 499748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 499848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "out vec4 result;\n" 499948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 500048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void main()\n" 500148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 500248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " result = vec4(0, 1, 2, 3);\n" 500348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 500448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " subroutine_uniform1(result.x);\n" 500548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " subroutine_uniform2(result.y);\n" 500648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " subroutine_uniform3(result.z);\n" 500748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 500848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " result.w += result.x + result.y + result.z;\n" 500948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n"; 501048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 501148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 501248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Initializes all GL objects required to run the test. */ 501348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid FunctionalTest9::initTest() 501448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 501548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 501648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 501748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Set up program object */ 501848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* xfb_varyings[] = { "result" }; 501948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 502048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const unsigned int n_xfb_varyings = sizeof(xfb_varyings) / sizeof(xfb_varyings[0]); 502148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!Utils::buildProgram(gl, getVertexShaderBody(), "", /* tc_body */ 502248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "", /* te_body */ 502348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "", /* gs_body */ 502448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "", /* fs_body */ 502548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos xfb_varyings, n_xfb_varyings, &m_vs_id, DE_NULL, /* out_tc_id */ 502648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos DE_NULL, /* out_te_id */ 502748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos DE_NULL, /* out_gs_id */ 502848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos DE_NULL, /* out_fs_id */ 502948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos &m_po_id)) 503048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 503148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos TCU_FAIL("Program failed to link successfully"); 503248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 503348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 503448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Set up a buffer object we will use to hold XFB data */ 503548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const unsigned int xfb_bo_size = static_cast<unsigned int>(sizeof(float) * 4 /* components */ * m_n_points_to_draw); 503648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 503748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.genBuffers(1, &m_xfb_bo_id); 503848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers() call failed."); 503948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 504048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_xfb_bo_id); 504148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() call failed."); 504248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 504348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* index */, m_xfb_bo_id); 504448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase() call failed."); 504548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 504648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, xfb_bo_size, DE_NULL, /* data */ 504748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GL_STATIC_COPY); 504848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() call failed."); 504948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 505048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Generate & bind a VAO */ 505148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.genVertexArrays(1, &m_vao_id); 505248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays() call failed."); 505348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 505448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.bindVertexArray(m_vao_id); 505548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() call failed."); 505648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 505748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 505848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Executes test iteration. 505948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 506048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed. 506148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos */ 506248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulostcu::TestNode::IterateResult FunctionalTest9::iterate() 506348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 506448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 506548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 506648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Do not execute the test if GL_ARB_shader_subroutine is not supported */ 506748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_shader_subroutine")) 506848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 506948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos throw tcu::NotSupportedError("GL_ARB_shader_subroutine is not supported."); 507048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 507148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos initTest(); 507248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 507348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Issue a draw call to make use of the three subroutine uniforms that we've defined */ 507448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.useProgram(m_po_id); 507548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed."); 507648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 507748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.beginTransformFeedback(GL_POINTS); 507848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback() call failed."); 507948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 508048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.drawArrays(GL_POINTS, 0 /* first */, m_n_points_to_draw); 508148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() call failed."); 508248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 508348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.endTransformFeedback(); 508448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback() call failed."); 508548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 508648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Map the XFB BO storage into process space */ 508748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::GLvoid* xfb_data_ptr = gl.mapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY); 508848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBuffer() call failed."); 508948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 509048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos verifyXFBData(xfb_data_ptr); 509148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 509248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER); 509348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer() call failed."); 509448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 509548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* All done */ 509648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_has_test_passed) 509748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 509848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 509948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 510048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else 510148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 510248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 510348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 510448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 510548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return STOP; 510648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 510748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 510848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Verifies the data XFBed out by the vertex shader. Should the data 510948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * be found invalid, m_has_test_passed will be set to false. 511048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 511148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param data_ptr XFB data. 511248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 511348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid FunctionalTest9::verifyXFBData(const glw::GLvoid* data_ptr) 511448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 511548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const float epsilon = 1e-5f; 511648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos bool should_continue = true; 511748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::GLfloat* traveller_ptr = (const glw::GLfloat*)data_ptr; 511848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 511948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (unsigned int n_point = 0; n_point < m_n_points_to_draw && should_continue; ++n_point) 512048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 512148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos tcu::Vec4 expected_result(0, 1, 2, 3); 512248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 512348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (unsigned int n_component = 0; n_component < 3 /* xyz */; ++n_component) 512448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 512548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos expected_result[n_component] += 0.123f + float(n_point); 512648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 512748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 512848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos expected_result[3 /* w */] += expected_result[0] + expected_result[1] + expected_result[2]; 512948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 513048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (de::abs(expected_result[0] - traveller_ptr[0]) > epsilon || 513148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos de::abs(expected_result[1] - traveller_ptr[1]) > epsilon || 513248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos de::abs(expected_result[2] - traveller_ptr[2]) > epsilon || 513348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos de::abs(expected_result[3] - traveller_ptr[3]) > epsilon) 513448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 513548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.getLog() << tcu::TestLog::Message << "XFBed data is invalid. Expected:" 513648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "(" 513748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << expected_result[0] << ", " << expected_result[1] << ", " << expected_result[2] << ", " 513848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << expected_result[3] << "), found:(" << traveller_ptr[0] << ", " << traveller_ptr[1] 513948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << ", " << traveller_ptr[2] << ", " << traveller_ptr[3] << ")." 514048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << tcu::TestLog::EndMessage; 514148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 514248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_has_test_passed = false; 514348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos should_continue = false; 514448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 514548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 514648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos traveller_ptr += 4; /* xyzw */ 514748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } /* for (all rendered points) */ 514848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 514948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 515048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Constructor 515148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 515248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param context CTS context 515348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 515448087f5f0eb08759ee763f98daf3b34becb74559Pyry HaulosFunctionalTest10::FunctionalTest10(deqp::Context& context) 515548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos : TestCase(context, "arrays_of_arrays_of_uniforms", "Verify that arrays of arrays of uniforms works as expected") 515648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 515748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 515848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 515948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Execute test 516048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 516148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return tcu::TestNode::STOP 516248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 516348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulostcu::TestNode::IterateResult FunctionalTest10::iterate() 516448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 516548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLchar* vertex_shader_code = "#version 400 core\n" 516648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "#extension GL_ARB_arrays_of_arrays : require\n" 516748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "#extension GL_ARB_shader_subroutine : require\n" 516848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 516948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "precision highp float;\n" 517048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 517148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "// Subroutine type\n" 517248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine int routine_type(in int iparam);\n" 517348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 517448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "// Subroutine definitions\n" 517548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine(routine_type) int increment(in int iparam)\n" 517648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 517748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " return iparam + 1;\n" 517848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 517948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 518048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine(routine_type) int decrement(in int iparam)\n" 518148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 518248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " return iparam - 1;\n" 518348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 518448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 518548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "// Sub routine uniform\n" 518648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine uniform routine_type routine[4][4];\n" 518748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 518848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "// Output\n" 518948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "out int out_result;\n" 519048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 519148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void main()\n" 519248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 519348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " int result = 0;\n" 519448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " \n" 519548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " for (uint j = 0; j < routine.length(); ++j)\n" 519648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " {\n" 519748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " for (uint i = 0; i < routine[j].length(); ++i)\n" 519848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " {\n" 519948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " result = routine[j][i](result);\n" 520048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " }\n" 520148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " }\n" 520248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " \n" 520348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " out_result = result;\n" 520448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 520548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n"; 520648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 520748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLchar* subroutine_names[] = { 520848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "increment", "decrement", 520948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos }; 521048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLuint n_subroutine_names = sizeof(subroutine_names) / sizeof(subroutine_names[0]); 521148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 521248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLchar* subroutine_uniform_names[] = { 521348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "routine[0][0]", "routine[1][0]", "routine[2][0]", "routine[3][0]", "routine[0][1]", "routine[1][1]", 521448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "routine[2][1]", "routine[3][1]", "routine[0][2]", "routine[1][2]", "routine[2][2]", "routine[3][2]", 521548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "routine[0][3]", "routine[1][3]", "routine[2][3]", "routine[3][3]" 521648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos }; 521748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLuint n_subroutine_uniform_names = 521848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos sizeof(subroutine_uniform_names) / sizeof(subroutine_uniform_names[0]); 521948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 522048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLchar* varying_name = "out_result"; 522148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLuint transform_feedback_buffer_size = sizeof(GLint); 522248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 522348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLuint configuration_increment[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; 522448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 522548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLuint configuration_decrement[16] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }; 522648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 522748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLuint configuration_mix[16] = { 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1 }; 522848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 522948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Do not execute the test if GL_ARB_shader_subroutine is not supported */ 523048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_shader_subroutine")) 523148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 523248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos throw tcu::NotSupportedError("GL_ARB_shader_subroutine is not supported."); 523348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 523448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 523548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Do not execute the test if GL_ARB_arrays_of_arrays is not supported */ 523648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_arrays_of_arrays")) 523748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 523848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos throw tcu::NotSupportedError("GL_ARB_arrays_of_arrays is not supported."); 523948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 524048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 524148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos bool result = true; 524248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 524348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* GL objects */ 524448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::program program(m_context); 524548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::buffer transform_feedback_buffer(m_context); 524648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::vertexArray vao(m_context); 524748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 524848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Init GL objects */ 524948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos program.build(0 /* cs */, 0 /* fs */, 0 /* gs */, 0 /* tcs */, 0 /* test */, vertex_shader_code, &varying_name, 525048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1 /* n_varyings */); 525148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 525248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos program.use(); 525348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 525448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos vao.generate(); 525548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos vao.bind(); 525648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 525748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos transform_feedback_buffer.generate(); 525848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos transform_feedback_buffer.update(GL_TRANSFORM_FEEDBACK_BUFFER, transform_feedback_buffer_size, 0 /* data */, 525948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GL_DYNAMIC_COPY); 526048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos transform_feedback_buffer.bindRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, 0, transform_feedback_buffer_size); 526148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 526248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Get subroutine indices */ 526348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLuint routine = 0; routine < n_subroutine_names; ++routine) 526448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 526548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_subroutine_indices[routine] = program.getSubroutineIndex(subroutine_names[routine], GL_VERTEX_SHADER); 526648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 526748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 526848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Get subroutine uniform locations */ 526948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLuint uniform = 0; uniform < n_subroutine_uniform_names; ++uniform) 527048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 527148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_subroutine_uniform_locations[uniform] = 527248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos program.getSubroutineUniformLocation(subroutine_uniform_names[uniform], GL_VERTEX_SHADER); 527348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 527448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 527548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Test */ 527648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLint increment_result = testDraw(configuration_increment); 527748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLint decrement_result = testDraw(configuration_decrement); 527848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLint mix_result = testDraw(configuration_mix); 527948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 528048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Verify */ 528148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (16 != increment_result) 528248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 528348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = false; 528448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 528548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 528648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (-16 != decrement_result) 528748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 528848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = false; 528948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 529048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (0 != mix_result) 529148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 529248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = false; 529348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 529448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 529548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Set test result */ 529648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (true == result) 529748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 529848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 529948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 530048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else 530148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 530248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_context.getTestContext().getLog() << tcu::TestLog::Message << "Error. Invalid result." 530348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << " Incrementation applied 16 times: " << increment_result 530448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << ". Decrementation applied 16 times: " << decrement_result 530548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << ". Incrementation and decrementation applied 8 times: " << mix_result 530648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << tcu::TestLog::EndMessage; 530748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 530848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 530948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 531048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 531148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Done */ 531248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return tcu::TestNode::STOP; 531348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 531448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 531548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Execute draw call and return captured varying 531648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 531748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param routine_indices Configuration of subroutine uniforms 531848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 531948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return Value of varying captured with transform feedback 532048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 532148087f5f0eb08759ee763f98daf3b34becb74559Pyry HaulosGLint FunctionalTest10::testDraw(const GLuint routine_indices[16]) const 532248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 532348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 532448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint subroutine_indices[16]; 532548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLuint n_subroutine_uniforms = sizeof(subroutine_indices) / sizeof(subroutine_indices[0]); 532648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 532748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Prepare subroutine uniform data */ 532848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLuint i = 0; i < n_subroutine_uniforms; ++i) 532948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 533048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLuint location = m_subroutine_uniform_locations[i]; 533148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 533248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos subroutine_indices[location] = m_subroutine_indices[routine_indices[i]]; 533348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 533448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 533548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Set up subroutine uniforms */ 533648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.uniformSubroutinesuiv(GL_VERTEX_SHADER, n_subroutine_uniforms, &subroutine_indices[0]); 533748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "UniformSubroutinesuiv"); 533848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 533948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Execute draw call with transform feedback */ 534048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.beginTransformFeedback(GL_POINTS); 534148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback"); 534248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 534348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.drawArrays(GL_POINTS, 0 /* first */, 1 /* count */); 534448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays"); 534548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 534648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.endTransformFeedback(); 534748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback"); 534848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 534948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Capture results */ 535048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLint* feedback_data = (GLint*)gl.mapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY); 535148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "MapBuffer"); 535248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 535348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLint result = feedback_data[0]; 535448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 535548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Unmap buffer */ 535648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER); 535748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "UnmapBuffer"); 535848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 535948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return result; 536048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 536148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 536248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/* Definitions of constants used by FunctionalTest11 */ 536348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosconst GLuint FunctionalTest11::m_texture_height = 32; 536448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosconst GLuint FunctionalTest11::m_texture_width = 32; 536548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 536648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Constructor 536748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 536848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param context CTS context 536948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 537048087f5f0eb08759ee763f98daf3b34becb74559Pyry HaulosFunctionalTest11::FunctionalTest11(deqp::Context& context) 537148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos : TestCase(context, "globals_sampling_output_discard_function_calls", "Verify that global variables, texture " 537248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "sampling, fragment output, fragment discard " 537348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "and function calls work as expected") 537448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 537548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 537648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 537748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Execute test 537848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 537948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return tcu::TestNode::STOP 538048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 538148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulostcu::TestNode::IterateResult FunctionalTest11::iterate() 538248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 538348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLchar* fragment_shader_code = 538448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "#version 400 core\n" 538548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "#extension GL_ARB_shader_subroutine : require\n" 538648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 538748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "precision highp float;\n" 538848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 538948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "// Output\n" 539048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "layout(location = 0) out vec4 out_color;\n" 539148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 539248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "// Global variables\n" 539348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "vec4 success_color;\n" 539448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "vec4 failure_color;\n" 539548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 539648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "// Samplers\n" 539748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "uniform sampler2D sampler_1;\n" 539848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "uniform sampler2D sampler_2;\n" 539948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 540048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "// Functions\n" 540148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "bool are_same(in vec4 left, in vec4 right)\n" 540248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 540348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " bvec4 result;\n" 540448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 540548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " result.x = (left.x == right.x);\n" 540648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " result.y = (left.y == right.y);\n" 540748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " result.z = (left.z == right.z);\n" 540848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " result.w = (left.w == right.w);\n" 540948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 541048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " return all(result);\n" 541148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 541248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 541348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "bool are_different(in vec4 left, in vec4 right)\n" 541448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 541548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " bvec4 result;\n" 541648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 541748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " result.x = (left.x != right.x);\n" 541848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " result.y = (left.y != right.y);\n" 541948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " result.z = (left.z != right.z);\n" 542048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " result.w = (left.w != right.w);\n" 542148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 542248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " return any(result);\n" 542348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 542448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 542548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "// Subroutine types\n" 542648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine void discard_fragment_type(void);\n" 542748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine void set_global_colors_type(void);\n" 542848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine vec4 sample_texture_type(in vec2);\n" 542948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine bool comparison_type(in vec4 left, in vec4 right);\n" 543048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine void test_type(void);\n" 543148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 543248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "// Subroutine definitions\n" 543348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "// discard_fragment_type\n" 543448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine(discard_fragment_type) void discard_yes(void)\n" 543548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 543648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " discard;\n" 543748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 543848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 543948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine(discard_fragment_type) void discard_no(void)\n" 544048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 544148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 544248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 544348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "// set_global_colors_type\n" 544448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine(set_global_colors_type) void red_pass_blue_fail(void)\n" 544548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 544648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " success_color = vec4(1, 0, 0, 1);\n" 544748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " failure_color = vec4(0, 0, 1, 1);\n" 544848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 544948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 545048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine(set_global_colors_type) void blue_pass_red_fail(void)\n" 545148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 545248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " success_color = vec4(0, 0, 1, 1);\n" 545348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " failure_color = vec4(1, 0, 0, 1);\n" 545448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 545548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 545648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "// sample_texture_type\n" 545748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine(sample_texture_type) vec4 first_sampler(in vec2 coord)\n" 545848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 545948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " return texture(sampler_1, coord);\n" 546048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 546148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 546248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine(sample_texture_type) vec4 second_sampler(in vec2 coord)\n" 546348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 546448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " return texture(sampler_2, coord);\n" 546548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 546648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 546748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "// comparison_type\n" 546848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine(comparison_type) bool check_equal(in vec4 left, in vec4 right)\n" 546948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 547048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " return are_same(left, right);\n" 547148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 547248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 547348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine(comparison_type) bool check_not_equal(in vec4 left, in vec4 right)\n" 547448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 547548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " return are_different(left, right);\n" 547648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 547748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 547848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "// Subroutine uniforms\n" 547948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine uniform discard_fragment_type discard_fragment;\n" 548048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine uniform set_global_colors_type set_global_colors;\n" 548148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine uniform sample_texture_type sample_texture;\n" 548248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine uniform comparison_type compare;\n" 548348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 548448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "// Subroutine definitions\n" 548548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "// test_type\n" 548648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine(test_type) void test_with_discard(void)\n" 548748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 548848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " discard_fragment();" 548948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 549048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " out_color = failure_color;\n" 549148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 549248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " set_global_colors();\n" 549348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 549448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " vec4 sampled_color = sample_texture(gl_PointCoord);\n" 549548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 549648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " bool comparison_result = compare(success_color, sampled_color);\n" 549748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 549848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " if (true == comparison_result)\n" 549948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " {\n" 550048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " out_color = success_color;\n" 550148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " }\n" 550248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " else\n" 550348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " {\n" 550448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " out_color = failure_color;\n" 550548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " }\n" 550648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 550748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 550848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine(test_type) void test_without_discard(void)\n" 550948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 551048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " set_global_colors();\n" 551148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 551248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " vec4 sampled_color = sample_texture(gl_PointCoord);\n" 551348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 551448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " bool comparison_result = compare(success_color, sampled_color);\n" 551548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 551648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " if (true == comparison_result)\n" 551748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " {\n" 551848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " out_color = success_color;\n" 551948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " }\n" 552048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " else\n" 552148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " {\n" 552248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " out_color = failure_color;\n" 552348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " }\n" 552448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 552548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 552648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "// Subroutine uniforms\n" 552748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine uniform test_type test;\n" 552848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 552948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void main()\n" 553048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 553148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " // Set colors\n" 553248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " success_color = vec4(0.5, 0.5, 0.5, 0.5);\n" 553348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " failure_color = vec4(0.5, 0.5, 0.5, 0.5);\n" 553448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 553548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " test();\n" 553648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 553748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n"; 553848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 553948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLchar* geometry_shader_code = "#version 400 core\n" 554048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "#extension GL_ARB_shader_subroutine : require\n" 554148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 554248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "precision highp float;\n" 554348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 554448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "layout(points) in;\n" 554548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "layout(triangle_strip, max_vertices = 4) out;\n" 554648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 554748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void main()\n" 554848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 554948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " gl_Position = vec4(-1, -1, 0, 1);\n" 555048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " EmitVertex();\n" 555148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " \n" 555248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " gl_Position = vec4(-1, 1, 0, 1);\n" 555348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " EmitVertex();\n" 555448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " \n" 555548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " gl_Position = vec4( 1, -1, 0, 1);\n" 555648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " EmitVertex();\n" 555748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " \n" 555848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " gl_Position = vec4( 1, 1, 0, 1);\n" 555948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " EmitVertex();\n" 556048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " \n" 556148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " EndPrimitive();\n" 556248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 556348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n"; 556448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 556548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLchar* vertex_shader_code = "#version 400 core\n" 556648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "#extension GL_ARB_shader_subroutine : require\n" 556748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 556848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "precision highp float;\n" 556948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 557048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void main()\n" 557148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 557248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 557348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n"; 557448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 557548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLchar* subroutine_names[][2] = { { "discard_yes", "discard_no" }, 557648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { "red_pass_blue_fail", "blue_pass_red_fail" }, 557748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { "first_sampler", "second_sampler" }, 557848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { "check_equal", "check_not_equal" }, 557948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { "test_with_discard", "test_without_discard" } }; 558048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLuint n_subroutine_types = sizeof(subroutine_names) / sizeof(subroutine_names[0]); 558148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 558248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLchar* subroutine_uniform_names[] = { "discard_fragment", "set_global_colors", "sample_texture", 558348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "compare", "test" }; 558448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLuint n_subroutine_uniform_names = 558548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos sizeof(subroutine_uniform_names) / sizeof(subroutine_uniform_names[0]); 558648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 558748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLchar* uniform_names[] = { 558848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "sampler_1", "sampler_2", 558948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos }; 559048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLuint n_uniform_names = sizeof(uniform_names) / sizeof(uniform_names[0]); 559148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 559248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Colors */ 559348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLubyte blue_color[4] = { 0, 0, 255, 255 }; 559448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLubyte clean_color[4] = { 0, 0, 0, 0 }; 559548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLubyte red_color[4] = { 255, 0, 0, 255 }; 559648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 559748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Configurations */ 559848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const testConfiguration test_configurations[] = { 559948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos testConfiguration( 560048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "Expect red color from 1st sampler", red_color, 1 /* discard_fragment : discard_no */, 560148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 0 /* set_global_colors : red_pass_blue_fail */, 0 /* sample_texture : first_sampler */, 560248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 0 /* compare : check_equal */, 0 /* test : test_with_discard */, 1 /* red */, 560348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 0 /* blue */), 560448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 560548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos testConfiguration( 560648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "Test \"without discard\" option, expect no blue color from 2nd sampler", blue_color, 560748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 0 /* discard_fragment : discard_yes */, 1 /* set_global_colors : blue_pass_red_fail */, 560848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1 /* sample_texture : second_sampler */, 1 /* compare : check_not_equal */, 560948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1 /* test : test_without_discard */, 0 /* blue */, 1 /* red */), 561048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 561148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos testConfiguration("Fragment shoud be discarded", clean_color, 0 /* discard_fragment : discard_yes */, 561248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 0 /* set_global_colors : red_pass_blue_fail */, 561348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 0 /* sample_texture : first_sampler */, 561448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 0 /* compare : check_equal */, 561548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 0 /* test : test_with_discard */, 1 /* red */, 0 /* blue */), 561648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 561748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos testConfiguration( 561848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "Expect blue color from 1st sampler", blue_color, 1 /* discard_fragment : discard_no */, 561948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1 /* set_global_colors : blue_pass_red_fail */, 0 /* sample_texture : first_sampler */, 562048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 0 /* compare : check_equal */, 0 /* test : test_with_discard */, 562148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 0 /* blue */, 1 /* red */), 562248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 562348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos testConfiguration( 562448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "Expect red color from 2nd sampler", red_color, 1 /* discard_fragment : discard_no */, 562548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 0 /* set_global_colors : red_pass_blue_fail */, 1 /* sample_texture : second_sampler */, 562648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 0 /* compare : check_equal */, 0 /* test : test_with_discard */, 562748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 0 /* blue */, 1 /* red */), 562848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 562948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos testConfiguration( 563048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "Expect no blue color from 2nd sampler", blue_color, 1 /* discard_fragment : discard_no */, 563148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1 /* set_global_colors : blue_pass_red_fail */, 1 /* sample_texture : second_sampler */, 563248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1 /* compare : check_not_equal */, 0 /* test : test_with_discard */, 563348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 0 /* blue */, 1 /* red */), 563448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos }; 563548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLuint n_test_cases = sizeof(test_configurations) / sizeof(test_configurations[0]); 563648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 563748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Do not execute the test if GL_ARB_shader_subroutine is not supported */ 563848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_shader_subroutine")) 563948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 564048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos throw tcu::NotSupportedError("GL_ARB_shader_subroutine is not supported."); 564148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 564248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 564348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* GL objects */ 564448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::texture blue_texture(m_context); 564548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::texture color_texture(m_context); 564648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::framebuffer framebuffer(m_context); 564748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::program program(m_context); 564848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::texture red_texture(m_context); 564948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::vertexArray vao(m_context); 565048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 565148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Init GL objects */ 565248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos program.build(0 /* cs */, fragment_shader_code /* fs */, geometry_shader_code /* gs */, 0 /* tcs */, 0 /* test */, 565348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos vertex_shader_code, 0 /* varying_names */, 0 /* n_varyings */); 565448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 565548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos program.use(); 565648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 565748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos vao.generate(); 565848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos vao.bind(); 565948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 566048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos blue_texture.create(m_texture_width, m_texture_height, GL_RGBA8); 566148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos color_texture.create(m_texture_width, m_texture_height, GL_RGBA8); 566248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos red_texture.create(m_texture_width, m_texture_height, GL_RGBA8); 566348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 566448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos framebuffer.generate(); 566548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos framebuffer.bind(); 566648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos framebuffer.attachTexture(GL_COLOR_ATTACHMENT0, color_texture.m_id, m_texture_width, m_texture_height); 566748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 566848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Get subroutine indices */ 566948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLuint type = 0; type < n_subroutine_types; ++type) 567048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 567148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_subroutine_indices[type][0] = program.getSubroutineIndex(subroutine_names[type][0], GL_FRAGMENT_SHADER); 567248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_subroutine_indices[type][1] = program.getSubroutineIndex(subroutine_names[type][1], GL_FRAGMENT_SHADER); 567348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 567448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 567548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Get subroutine uniform locations */ 567648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLuint uniform = 0; uniform < n_subroutine_uniform_names; ++uniform) 567748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 567848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_subroutine_uniform_locations[uniform] = 567948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos program.getSubroutineUniformLocation(subroutine_uniform_names[uniform], GL_FRAGMENT_SHADER); 568048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 568148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 568248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Get uniform locations */ 568348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLuint i = 0; i < n_uniform_names; ++i) 568448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 568548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_uniform_locations[i] = program.getUniformLocation(uniform_names[i]); 568648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 568748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 568848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Prepare textures */ 568948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos fillTexture(blue_texture, blue_color); 569048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos fillTexture(color_texture, clean_color); 569148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos fillTexture(red_texture, red_color); 569248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 569348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_source_textures[0] = blue_texture.m_id; 569448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_source_textures[1] = red_texture.m_id; 569548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 569648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos framebuffer.clearColor(0.0f, 0.0f, 0.0f, 0.0f); 569748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 569848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Test */ 569948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos bool result = true; 570048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLuint i = 0; i < n_test_cases; ++i) 570148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 570248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Clean output texture */ 570348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos framebuffer.clear(GL_COLOR_BUFFER_BIT); 570448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 570548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Execute test */ 570648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (false == testDraw(test_configurations[i].m_routines, test_configurations[i].m_samplers, 570748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos test_configurations[i].m_expected_color, color_texture)) 570848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 570948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_context.getTestContext().getLog() 571048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << tcu::TestLog::Message << "Error. Failure for configuration: " << test_configurations[i].m_description 571148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << tcu::TestLog::EndMessage; 571248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 571348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = false; 571448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 571548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 571648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 571748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Set result */ 571848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (true == result) 571948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 572048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 572148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 572248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else 572348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 572448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 572548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 572648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 572748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Done */ 572848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return tcu::TestNode::STOP; 572948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 573048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 573148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Fill texture with specified color 573248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 573348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param texture Texture instance 573448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param color Color 573548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 573648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid FunctionalTest11::fillTexture(Utils::texture& texture, const glw::GLubyte color[4]) const 573748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 573848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::vector<GLubyte> texture_data; 573948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 574048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Prepare texture data */ 574148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos texture_data.resize(m_texture_width * m_texture_height * 4); 574248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 574348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLuint y = 0; y < m_texture_height; ++y) 574448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 574548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLuint line_offset = y * m_texture_width * 4; 574648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 574748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLuint x = 0; x < m_texture_width; ++x) 574848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 574948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLuint point_offset = x * 4 + line_offset; 575048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 575148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos texture_data[point_offset + 0] = color[0]; /* red */ 575248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos texture_data[point_offset + 1] = color[1]; /* green */ 575348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos texture_data[point_offset + 2] = color[2]; /* blue */ 575448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos texture_data[point_offset + 3] = color[3]; /* alpha */ 575548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 575648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 575748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 575848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos texture.update(m_texture_width, m_texture_height, GL_RGBA, GL_UNSIGNED_BYTE, &texture_data[0]); 575948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 576048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 576148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Execute draw call and verify results 576248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 576348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param routine_configuration Configurations of routines to be used 576448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param sampler_configuration Configuration of textures to be bound to samplers 576548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param expected_color Expected color of result image 576648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 576748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return true if result image is filled with expected color, false otherwise 576848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 576948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosbool FunctionalTest11::testDraw(const glw::GLuint routine_configuration[5], const glw::GLuint sampler_configuration[2], 577048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::GLubyte expected_color[4], Utils::texture& color_texture) const 577148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 577248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 577348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLint n_samplers = 2; 577448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLint n_subroutine_uniforms = 5; 577548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint subroutine_indices[5]; 577648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 577748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Set samplers */ 577848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLuint i = 0; i < n_samplers; ++i) 577948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 578048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLuint location = m_uniform_locations[i]; 578148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLuint texture = m_source_textures[sampler_configuration[i]]; 578248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 578348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.activeTexture(GL_TEXTURE0 + i); 578448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "ActiveTexture"); 578548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 578648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.bindTexture(GL_TEXTURE_2D, texture); 578748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture"); 578848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 578948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.uniform1i(location, i); 579048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "Uniform1i"); 579148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 579248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 579348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.activeTexture(GL_TEXTURE0 + 0); 579448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 579548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Set subroutine uniforms */ 579648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLuint i = 0; i < n_subroutine_uniforms; ++i) 579748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 579848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLuint location = m_subroutine_uniform_locations[i]; 579948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLuint routine = routine_configuration[i]; 580048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 580148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos subroutine_indices[location] = m_subroutine_indices[i][routine]; 580248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 580348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 580448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.uniformSubroutinesuiv(GL_FRAGMENT_SHADER, 5, subroutine_indices); 580548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "UniformSubroutinesuiv"); 580648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 580748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Draw */ 580848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.drawArrays(GL_POINTS, 0 /* first */, 1 /* count */); 580948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays"); 581048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 581148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Capture result */ 581248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::vector<GLubyte> captured_data; 581348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos captured_data.resize(m_texture_width * m_texture_height * 4); 581448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 581548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos color_texture.get(GL_RGBA, GL_UNSIGNED_BYTE, &captured_data[0]); 581648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 581748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Verify result */ 581848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLuint y = 0; y < m_texture_height; ++y) 581948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 582048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLuint line_offset = y * m_texture_width * 4; 582148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 582248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLuint x = 0; x < m_texture_width; ++x) 582348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 582448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLuint point_offset = x * 4 + line_offset; 582548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos bool is_as_expected = true; 582648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 582748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos is_as_expected = is_as_expected && (expected_color[0] == captured_data[point_offset + 0]); /* red */ 582848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos is_as_expected = is_as_expected && (expected_color[1] == captured_data[point_offset + 1]); /* green */ 582948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos is_as_expected = is_as_expected && (expected_color[2] == captured_data[point_offset + 2]); /* blue */ 583048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos is_as_expected = is_as_expected && (expected_color[3] == captured_data[point_offset + 3]); /* alpha */ 583148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 583248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (false == is_as_expected) 583348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 583448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return false; 583548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 583648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 583748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 583848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 583948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Done */ 584048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return true; 584148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 584248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 584348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/* Constatns used by FunctionalTest12 */ 584448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosconst glw::GLuint FunctionalTest12::m_texture_height = 16; 584548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosconst glw::GLuint FunctionalTest12::m_texture_width = 16; 584648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 584748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Constructor 584848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 584948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param context CTS context 585048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 585148087f5f0eb08759ee763f98daf3b34becb74559Pyry HaulosFunctionalTest12::FunctionalTest12(deqp::Context& context) 585248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos : TestCase(context, "ssbo_atomic_image_load_store", 585348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "Verify that SSBO, atomic counters and image load store work as expected") 585448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_left_image(0) 585548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_right_image(0) 585648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 585748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 585848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 585948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Execute test 586048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 586148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return tcu::TestNode::STOP 586248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 586348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulostcu::TestNode::IterateResult FunctionalTest12::iterate() 586448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 586548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Do not execute the test if GL_ARB_shader_subroutine is not supported */ 586648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_shader_subroutine")) 586748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 586848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos throw tcu::NotSupportedError("GL_ARB_shader_subroutine is not supported."); 586948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 587048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 587148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos bool result = true; 587248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 587348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Test atomic counters */ 587448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (true == m_context.getContextInfo().isExtensionSupported("GL_ARB_shader_atomic_counters")) 587548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 587648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (false == testAtomic()) 587748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 587848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = false; 587948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 588048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 588148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 588248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Test shader storage buffer */ 588348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (true == m_context.getContextInfo().isExtensionSupported("GL_ARB_shader_storage_buffer_object")) 588448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 588548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (false == testSSBO()) 588648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 588748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = false; 588848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 588948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 589048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 589148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Test image load store */ 589248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (true == m_context.getContextInfo().isExtensionSupported("GL_ARB_shader_image_load_store")) 589348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 589448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (false == testImage()) 589548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 589648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = false; 589748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 589848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 589948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 590048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Set result */ 590148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (true == result) 590248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 590348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 590448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 590548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else 590648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 590748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 590848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 590948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 591048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Done */ 591148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return tcu::TestNode::STOP; 591248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 591348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 591448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Fill texture with specified color 591548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 591648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param texture Texture instance 591748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param color Color 591848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 591948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid FunctionalTest12::fillTexture(Utils::texture& texture, const glw::GLuint color[4]) const 592048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 592148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::vector<GLuint> texture_data; 592248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 592348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Prepare texture data */ 592448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos texture_data.resize(m_texture_width * m_texture_height * 4); 592548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 592648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLuint y = 0; y < m_texture_height; ++y) 592748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 592848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLuint line_offset = y * m_texture_width * 4; 592948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 593048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLuint x = 0; x < m_texture_width; ++x) 593148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 593248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLuint point_offset = x * 4 + line_offset; 593348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 593448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos texture_data[point_offset + 0] = color[0]; /* red */ 593548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos texture_data[point_offset + 1] = color[1]; /* green */ 593648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos texture_data[point_offset + 2] = color[2]; /* blue */ 593748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos texture_data[point_offset + 3] = color[3]; /* alpha */ 593848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 593948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 594048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 594148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos texture.update(m_texture_width, m_texture_height, GL_RGBA_INTEGER, GL_UNSIGNED_INT, &texture_data[0]); 594248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 594348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 594448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Test atomic counters 594548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 594648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return true if test pass, false otherwise 594748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 594848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosbool FunctionalTest12::testAtomic() 594948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 595048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLchar* fragment_shader_code = "#version 400 core\n" 595148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "#extension GL_ARB_shader_atomic_counters : require\n" 595248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "#extension GL_ARB_shader_subroutine : require\n" 595348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 595448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "precision highp float;\n" 595548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 595648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "layout(location = 0) out uint out_color;\n" 595748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 595848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "layout(binding = 0, offset = 8) uniform atomic_uint one;\n" 595948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "layout(binding = 0, offset = 4) uniform atomic_uint two;\n" 596048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "layout(binding = 0, offset = 0) uniform atomic_uint three;\n" 596148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 596248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine void atomic_routine(void)\n;" 596348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 596448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine(atomic_routine) void increment_two(void)\n" 596548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 596648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " out_color = atomicCounterIncrement(two);\n" 596748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 596848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 596948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine(atomic_routine) void decrement_three(void)\n" 597048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 597148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " out_color = atomicCounterDecrement(three);\n" 597248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 597348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 597448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine(atomic_routine) void read_one(void)\n" 597548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 597648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " out_color = atomicCounter(one);\n" 597748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 597848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 597948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine uniform atomic_routine routine;\n" 598048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 598148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void main()\n" 598248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 598348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " routine();\n" 598448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 598548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n"; 598648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 598748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLchar* geometry_shader_code = "#version 400 core\n" 598848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "#extension GL_ARB_shader_subroutine : require\n" 598948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 599048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "precision highp float;\n" 599148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 599248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "layout(points) in;\n" 599348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "layout(triangle_strip, max_vertices = 4) out;\n" 599448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 599548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void main()\n" 599648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 599748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " gl_Position = vec4(-1, -1, 0, 1);\n" 599848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " EmitVertex();\n" 599948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " \n" 600048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " gl_Position = vec4(-1, 1, 0, 1);\n" 600148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " EmitVertex();\n" 600248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " \n" 600348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " gl_Position = vec4( 1, -1, 0, 1);\n" 600448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " EmitVertex();\n" 600548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " \n" 600648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " gl_Position = vec4( 1, 1, 0, 1);\n" 600748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " EmitVertex();\n" 600848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " \n" 600948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " EndPrimitive();\n" 601048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 601148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n"; 601248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 601348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLchar* vertex_shader_code = "#version 400 core\n" 601448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "#extension GL_ARB_shader_subroutine : require\n" 601548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 601648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "precision highp float;\n" 601748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 601848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void main()\n" 601948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 602048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 602148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n"; 602248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 602348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLchar* subroutine_names[] = { "increment_two", "decrement_three", "read_one" }; 602448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 602548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Test data */ 602648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const glw::GLuint atomic_buffer_data[] = { m_texture_width * m_texture_height, 602748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_texture_width * m_texture_height, 602848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_texture_width * m_texture_height }; 602948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 603048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const glw::GLuint expected_incremented_two[] = { atomic_buffer_data[0], 2 * atomic_buffer_data[1], 603148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos atomic_buffer_data[2] }; 603248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 603348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const glw::GLuint expected_decremented_three[] = { 0, expected_incremented_two[1], 603448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos expected_incremented_two[2] }; 603548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 603648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const glw::GLuint expected_read_one[] = { expected_decremented_three[0], expected_decremented_three[1], 603748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos expected_decremented_three[2] }; 603848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 603948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* GL objects */ 604048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::buffer atomic_buffer(m_context); 604148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::texture color_texture(m_context); 604248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::framebuffer framebuffer(m_context); 604348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::program program(m_context); 604448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::vertexArray vao(m_context); 604548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 604648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Init GL objects */ 604748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos program.build(0 /* cs */, fragment_shader_code /* fs */, geometry_shader_code /* gs */, 0 /* tcs */, 0 /* test */, 604848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos vertex_shader_code, 0 /* varying_names */, 0 /* n_varyings */); 604948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 605048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos program.use(); 605148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 605248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos vao.generate(); 605348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos vao.bind(); 605448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 605548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos color_texture.create(m_texture_width, m_texture_height, GL_R32UI); 605648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 605748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos atomic_buffer.generate(); 605848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos atomic_buffer.update(GL_ATOMIC_COUNTER_BUFFER, sizeof(atomic_buffer_data), (GLvoid*)atomic_buffer_data, 605948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GL_STATIC_DRAW); 606048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos atomic_buffer.bindRange(GL_ATOMIC_COUNTER_BUFFER, 0 /* index */, 0 /* offset */, sizeof(atomic_buffer_data)); 606148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 606248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos framebuffer.generate(); 606348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos framebuffer.bind(); 606448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos framebuffer.attachTexture(GL_COLOR_ATTACHMENT0, color_texture.m_id, m_texture_width, m_texture_height); 606548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos framebuffer.clearColor(0.0f, 0.0f, 0.0f, 0.0f); 606648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos framebuffer.clear(GL_COLOR_BUFFER_BIT); 606748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 606848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Subroutine indices */ 606948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint increment_two = program.getSubroutineIndex(subroutine_names[0], GL_FRAGMENT_SHADER); 607048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint decrement_three = program.getSubroutineIndex(subroutine_names[1], GL_FRAGMENT_SHADER); 607148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint read_one = program.getSubroutineIndex(subroutine_names[2], GL_FRAGMENT_SHADER); 607248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 607348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Test */ 607448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos bool result = true; 607548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 607648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (false == testAtomicDraw(increment_two, expected_incremented_two)) 607748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 607848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = false; 607948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 608048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 608148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (false == testAtomicDraw(decrement_three, expected_decremented_three)) 608248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 608348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = false; 608448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 608548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 608648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (false == testAtomicDraw(read_one, expected_read_one)) 608748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 608848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = false; 608948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 609048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 609148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Done */ 609248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return result; 609348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 609448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 609548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Execture draw call and verify results 609648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 609748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param subroutine_index Index of subroutine that shall be used during draw call 609848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param expected_results Expected results 609948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 610048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return true if results are as expected, false otherwise 610148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 610248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosbool FunctionalTest12::testAtomicDraw(GLuint subroutine_index, const GLuint expected_results[3]) const 610348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 610448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 610548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 610648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Set subroutine uniforms */ 610748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.uniformSubroutinesuiv(GL_FRAGMENT_SHADER, 1, &subroutine_index); 610848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "UniformSubroutinesuiv"); 610948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 611048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Draw */ 611148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.drawArrays(GL_POINTS, 0 /* first */, 1 /* count */); 611248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays"); 611348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 611448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Capture results */ 611548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint* atomic_results = (GLuint*)gl.mapBuffer(GL_ATOMIC_COUNTER_BUFFER, GL_READ_ONLY); 611648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "MapBuffer"); 611748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 611848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Verify */ 611948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos bool result = (0 == memcmp(expected_results, atomic_results, 3 * sizeof(GLuint))); 612048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 612148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (false == result) 612248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 612348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_context.getTestContext().getLog() 612448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << tcu::TestLog::Message << "Error. Invalid result. " 612548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << "Result: [ " << atomic_results[0] << ", " << atomic_results[1] << ", " << atomic_results[2] << " ] " 612648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << "Expected: [ " << expected_results[0] << ", " << expected_results[1] << ", " << expected_results[2] 612748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << " ]" << tcu::TestLog::EndMessage; 612848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 612948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 613048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Unmap buffer */ 613148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.unmapBuffer(GL_ATOMIC_COUNTER_BUFFER); 613248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "UnmapBuffer"); 613348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 613448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Done */ 613548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return result; 613648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 613748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 613848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Test image load store 613948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 614048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return true if test pass, false otherwise 614148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 614248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosbool FunctionalTest12::testImage() 614348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 614448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLchar* fragment_shader_code = 614548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "#version 400 core\n" 614648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "#extension GL_ARB_shader_image_load_store : require\n" 614748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "#extension GL_ARB_shader_subroutine : require\n" 614848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 614948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "precision highp float;\n" 615048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 615148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "layout(location = 0) out uvec4 out_color;\n" 615248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 615348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "layout(rgba32ui) uniform uimage2D left_image;\n" 615448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "layout(rgba32ui) uniform uimage2D right_image;\n" 615548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 615648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine void image_routine(void);\n" 615748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 615848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine(image_routine) void left_to_right(void)\n" 615948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 616048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " out_color = imageLoad (left_image, ivec2(gl_FragCoord.xy));\n" 616148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " imageStore(right_image, ivec2(gl_FragCoord.xy), out_color);\n" 616248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 616348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 616448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine(image_routine) void right_to_left(void)\n" 616548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 616648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " out_color = imageLoad (right_image, ivec2(gl_FragCoord.xy));\n" 616748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " imageStore(left_image, ivec2(gl_FragCoord.xy), out_color);\n" 616848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 616948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 617048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine uniform image_routine routine;\n" 617148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 617248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void main()\n" 617348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 617448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " routine();\n" 617548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 617648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n"; 617748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 617848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLchar* geometry_shader_code = "#version 400 core\n" 617948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "#extension GL_ARB_shader_subroutine : require\n" 618048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 618148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "precision highp float;\n" 618248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 618348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "layout(points) in;\n" 618448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "layout(triangle_strip, max_vertices = 4) out;\n" 618548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 618648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void main()\n" 618748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 618848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " gl_Position = vec4(-1, -1, 0, 1);\n" 618948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " EmitVertex();\n" 619048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " \n" 619148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " gl_Position = vec4(-1, 1, 0, 1);\n" 619248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " EmitVertex();\n" 619348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " \n" 619448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " gl_Position = vec4( 1, -1, 0, 1);\n" 619548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " EmitVertex();\n" 619648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " \n" 619748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " gl_Position = vec4( 1, 1, 0, 1);\n" 619848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " EmitVertex();\n" 619948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " \n" 620048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " EndPrimitive();\n" 620148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 620248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n"; 620348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 620448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLchar* vertex_shader_code = "#version 400 core\n" 620548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "#extension GL_ARB_shader_subroutine : require\n" 620648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 620748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "precision highp float;\n" 620848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 620948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void main()\n" 621048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 621148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 621248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n"; 621348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 621448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLchar* subroutine_names[] = { "left_to_right", "right_to_left" }; 621548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 621648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLchar* uniform_names[] = { "left_image", "right_image" }; 621748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 621848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Test data */ 621948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLuint blue_color[4] = { 0, 0, 255, 255 }; 622048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLuint clean_color[4] = { 16, 32, 64, 128 }; 622148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLuint red_color[4] = { 255, 0, 0, 255 }; 622248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 622348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* GL objects */ 622448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::texture blue_texture(m_context); 622548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::texture destination_texture(m_context); 622648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::texture color_texture(m_context); 622748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::framebuffer framebuffer(m_context); 622848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::program program(m_context); 622948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::texture red_texture(m_context); 623048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::vertexArray vao(m_context); 623148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 623248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Init GL objects */ 623348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos program.build(0 /* cs */, fragment_shader_code /* fs */, geometry_shader_code /* gs */, 0 /* tcs */, 0 /* test */, 623448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos vertex_shader_code, 0 /* varying_names */, 0 /* n_varyings */); 623548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 623648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos program.use(); 623748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 623848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos vao.generate(); 623948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos vao.bind(); 624048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 624148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos blue_texture.create(m_texture_width, m_texture_height, GL_RGBA32UI); 624248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos destination_texture.create(m_texture_width, m_texture_height, GL_RGBA32UI); 624348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos color_texture.create(m_texture_width, m_texture_height, GL_RGBA32UI); 624448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos red_texture.create(m_texture_width, m_texture_height, GL_RGBA32UI); 624548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 624648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos fillTexture(blue_texture, blue_color); 624748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos fillTexture(destination_texture, clean_color); 624848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos fillTexture(red_texture, red_color); 624948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 625048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos framebuffer.generate(); 625148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos framebuffer.bind(); 625248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos framebuffer.attachTexture(GL_COLOR_ATTACHMENT0, color_texture.m_id, m_texture_width, m_texture_height); 625348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos framebuffer.clearColor(0.0f, 0.0f, 0.0f, 0.0f); 625448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos framebuffer.clear(GL_COLOR_BUFFER_BIT); 625548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 625648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Subroutine indices */ 625748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint left_to_right = program.getSubroutineIndex(subroutine_names[0], GL_FRAGMENT_SHADER); 625848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint right_to_left = program.getSubroutineIndex(subroutine_names[1], GL_FRAGMENT_SHADER); 625948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 626048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Uniform locations */ 626148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_left_image = program.getUniformLocation(uniform_names[0]); 626248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_right_image = program.getUniformLocation(uniform_names[1]); 626348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 626448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Test */ 626548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos bool result = true; 626648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 626748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (false == testImageDraw(left_to_right, blue_texture, destination_texture, blue_color, blue_color)) 626848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 626948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = false; 627048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 627148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 627248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (false == testImageDraw(left_to_right, red_texture, destination_texture, red_color, red_color)) 627348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 627448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = false; 627548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 627648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 627748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (false == testImageDraw(right_to_left, destination_texture, blue_texture, blue_color, blue_color)) 627848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 627948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = false; 628048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 628148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 628248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (false == testImageDraw(right_to_left, destination_texture, red_texture, red_color, red_color)) 628348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 628448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = false; 628548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 628648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 628748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (false == testImageDraw(left_to_right, blue_texture, red_texture, blue_color, blue_color)) 628848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 628948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = false; 629048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 629148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 629248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Done */ 629348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return result; 629448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 629548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 629648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Execute draw call and verifies results 629748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 629848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param subroutine_index Index of subroutine that shall be used during draw call 629948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param left "Left" texture 630048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param right "Right" texture 630148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param expected_left_color Expected color of "left" texture 630248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param expected_right_color Expected color of "right" texture 630348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 630448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return true if verification result is positive, false otherwise 630548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 630648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosbool FunctionalTest12::testImageDraw(GLuint subroutine_index, Utils::texture& left, Utils::texture& right, 630748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLuint expected_left_color[4], const GLuint expected_right_color[4]) const 630848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 630948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 631048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 631148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Set subroutine uniforms */ 631248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.uniformSubroutinesuiv(GL_FRAGMENT_SHADER, 1, &subroutine_index); 631348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "UniformSubroutinesuiv"); 631448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 631548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Set up image units */ 631648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.uniform1i(m_left_image, 0); 631748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "Uniform1i"); 631848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 631948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.uniform1i(m_right_image, 1); 632048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "Uniform1i"); 632148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 632248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.bindImageTexture(0, left.m_id, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32UI); 632348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "BindImageTexture"); 632448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 632548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.bindImageTexture(1, right.m_id, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32UI); 632648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "BindImageTexture"); 632748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 632848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Draw */ 632948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.drawArrays(GL_POINTS, 0 /* first */, 1 /* count */); 633048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays"); 633148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 633248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Verify results */ 633348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos bool result = true; 633448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 633548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (false == verifyTexture(left, expected_left_color)) 633648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 633748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_context.getTestContext().getLog() << tcu::TestLog::Message 633848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << "Error. Invalid result. Left texture is filled with wrong color." 633948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << tcu::TestLog::EndMessage; 634048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = false; 634148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 634248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 634348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (false == verifyTexture(right, expected_right_color)) 634448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 634548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_context.getTestContext().getLog() << tcu::TestLog::Message 634648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << "Error. Invalid result. Right texture is filled with wrong color." 634748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << tcu::TestLog::EndMessage; 634848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = false; 634948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 635048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 635148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Done */ 635248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return result; 635348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 635448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 635548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Test shader storage buffer 635648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 635748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return true if test pass, false otherwise 635848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 635948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosbool FunctionalTest12::testSSBO() 636048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 636148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLchar* fragment_shader_code = "#version 400 core\n" 636248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "#extension GL_ARB_shader_storage_buffer_object : require\n" 636348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "#extension GL_ARB_shader_subroutine : require\n" 636448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 636548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "precision highp float;\n" 636648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 636748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "layout(location = 0) out uvec4 out_color;\n" 636848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 636948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "layout(std140, binding = 0) buffer Buffer\n" 637048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 637148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " uvec4 entry;\n" 637248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "};\n" 637348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 637448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine void ssbo_routine(void)\n;" 637548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 637648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine(ssbo_routine) void increment(void)\n" 637748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 637848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " out_color.x = atomicAdd(entry.x, 1);\n" 637948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " out_color.y = atomicAdd(entry.y, 1);\n" 638048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " out_color.z = atomicAdd(entry.z, 1);\n" 638148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " out_color.w = atomicAdd(entry.w, 1);\n" 638248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 638348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 638448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine(ssbo_routine) void decrement(void)\n" 638548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 638648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " out_color.x = atomicAdd(entry.x, -1);\n" 638748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " out_color.y = atomicAdd(entry.y, -1);\n" 638848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " out_color.z = atomicAdd(entry.z, -1);\n" 638948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " out_color.w = atomicAdd(entry.w, -1);\n" 639048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 639148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 639248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine uniform ssbo_routine routine;\n" 639348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 639448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void main()\n" 639548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 639648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " routine();\n" 639748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 639848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n"; 639948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 640048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLchar* geometry_shader_code = "#version 400 core\n" 640148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "#extension GL_ARB_shader_subroutine : require\n" 640248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 640348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "precision highp float;\n" 640448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 640548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "layout(points) in;\n" 640648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "layout(triangle_strip, max_vertices = 4) out;\n" 640748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 640848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void main()\n" 640948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 641048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " gl_Position = vec4(-1, -1, 0, 1);\n" 641148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " EmitVertex();\n" 641248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " \n" 641348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " gl_Position = vec4(-1, 1, 0, 1);\n" 641448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " EmitVertex();\n" 641548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " \n" 641648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " gl_Position = vec4( 1, -1, 0, 1);\n" 641748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " EmitVertex();\n" 641848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " \n" 641948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " gl_Position = vec4( 1, 1, 0, 1);\n" 642048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " EmitVertex();\n" 642148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " \n" 642248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " EndPrimitive();\n" 642348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 642448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n"; 642548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 642648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLchar* vertex_shader_code = "#version 400 core\n" 642748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "#extension GL_ARB_shader_subroutine : require\n" 642848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 642948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "precision highp float;\n" 643048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 643148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void main()\n" 643248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 643348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 643448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n"; 643548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 643648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLchar* subroutine_names[] = { "increment", "decrement" }; 643748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 643848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Test data */ 643948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const glw::GLuint buffer_data[] = { m_texture_width * m_texture_height + 1, 644048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_texture_width * m_texture_height + 2, 644148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_texture_width * m_texture_height + 3, 644248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_texture_width * m_texture_height + 4 }; 644348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 644448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const glw::GLuint expected_incremented[] = { m_texture_width * m_texture_height + buffer_data[0], 644548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_texture_width * m_texture_height + buffer_data[1], 644648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_texture_width * m_texture_height + buffer_data[2], 644748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_texture_width * m_texture_height + buffer_data[3] }; 644848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 644948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const glw::GLuint expected_decremented[] = { buffer_data[0], buffer_data[1], buffer_data[2], 645048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos buffer_data[3] }; 645148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 645248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* GL objects */ 645348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::buffer buffer(m_context); 645448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::texture color_texture(m_context); 645548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::framebuffer framebuffer(m_context); 645648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::program program(m_context); 645748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::vertexArray vao(m_context); 645848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 645948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Init GL objects */ 646048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos program.build(0 /* cs */, fragment_shader_code /* fs */, geometry_shader_code /* gs */, 0 /* tcs */, 0 /* test */, 646148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos vertex_shader_code, 0 /* varying_names */, 0 /* n_varyings */); 646248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 646348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos program.use(); 646448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 646548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos vao.generate(); 646648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos vao.bind(); 646748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 646848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos color_texture.create(m_texture_width, m_texture_height, GL_RGBA32UI); 646948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 647048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos buffer.generate(); 647148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos buffer.update(GL_SHADER_STORAGE_BUFFER, sizeof(buffer_data), (GLvoid*)buffer_data, GL_STATIC_DRAW); 647248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos buffer.bindRange(GL_SHADER_STORAGE_BUFFER, 0 /* index */, 0 /* offset */, sizeof(buffer_data)); 647348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 647448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos framebuffer.generate(); 647548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos framebuffer.bind(); 647648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos framebuffer.attachTexture(GL_COLOR_ATTACHMENT0, color_texture.m_id, m_texture_width, m_texture_height); 647748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos framebuffer.clearColor(0.0f, 0.0f, 0.0f, 0.0f); 647848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos framebuffer.clear(GL_COLOR_BUFFER_BIT); 647948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 648048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Subroutine indices */ 648148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint increment = program.getSubroutineIndex(subroutine_names[0], GL_FRAGMENT_SHADER); 648248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint decrement = program.getSubroutineIndex(subroutine_names[1], GL_FRAGMENT_SHADER); 648348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 648448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Test */ 648548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos bool result = true; 648648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 648748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (false == testSSBODraw(increment, expected_incremented)) 648848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 648948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = false; 649048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 649148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 649248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (false == testSSBODraw(decrement, expected_decremented)) 649348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 649448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = false; 649548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 649648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 649748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Done */ 649848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return result; 649948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 650048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 650148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Execute draw call and verify results 650248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 650348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param subroutine_index Index of subroutine that shall be used by draw call 650448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param expected_results Expected results 650548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 650648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 650748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 650848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosbool FunctionalTest12::testSSBODraw(GLuint subroutine_index, const GLuint expected_results[4]) const 650948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 651048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 651148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 651248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Set subroutine uniforms */ 651348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.uniformSubroutinesuiv(GL_FRAGMENT_SHADER, 1, &subroutine_index); 651448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "UniformSubroutinesuiv"); 651548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 651648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Draw */ 651748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.drawArrays(GL_POINTS, 0 /* first */, 1 /* count */); 651848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays"); 651948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 652048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Capture results */ 652148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint* ssbo_results = (GLuint*)gl.mapBuffer(GL_SHADER_STORAGE_BUFFER, GL_READ_ONLY); 652248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "MapBuffer"); 652348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 652448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Verify */ 652548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos bool result = (0 == memcmp(expected_results, ssbo_results, 4 * sizeof(GLuint))); 652648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 652748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (false == result) 652848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 652948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_context.getTestContext().getLog() << tcu::TestLog::Message << "Error. Invalid result. " 653048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << "Result: [ " << ssbo_results[0] << ", " << ssbo_results[1] << ", " 653148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << ssbo_results[2] << ", " << ssbo_results[3] << " ] " 653248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << "Expected: [ " << expected_results[0] << ", " << expected_results[1] 653348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << ", " << expected_results[2] << ", " << expected_results[3] << " ]" 653448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << tcu::TestLog::EndMessage; 653548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 653648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 653748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Unmap buffer */ 653848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.unmapBuffer(GL_SHADER_STORAGE_BUFFER); 653948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "UnmapBuffer"); 654048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 654148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Done */ 654248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return result; 654348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 654448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 654548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Check if texture is filled with expected color 654648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 654748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param texture Texture instance 654848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param expected_color Expected color 654948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 655048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return true if texture is filled with specified color, false otherwise 655148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 655248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosbool FunctionalTest12::verifyTexture(Utils::texture& texture, const GLuint expected_color[4]) const 655348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 655448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::vector<GLuint> results; 655548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos results.resize(m_texture_width * m_texture_height * 4); 655648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 655748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos texture.get(GL_RGBA_INTEGER, GL_UNSIGNED_INT, &results[0]); 655848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 655948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLuint y = 0; y < m_texture_height; ++y) 656048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 656148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLuint line_offset = y * m_texture_width * 4; 656248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 656348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLuint x = 0; x < m_texture_width; ++x) 656448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 656548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLuint point_offset = line_offset + x * 4; 656648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos bool result = true; 656748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 656848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = result && (results[point_offset + 0] == expected_color[0]); 656948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = result && (results[point_offset + 1] == expected_color[1]); 657048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = result && (results[point_offset + 2] == expected_color[2]); 657148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = result && (results[point_offset + 3] == expected_color[3]); 657248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 657348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (false == result) 657448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 657548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return false; 657648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 657748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 657848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 657948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 658048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return true; 658148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 658248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 658348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Constructor. 658448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 658548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param context Rendering context. 658648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 658748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 658848087f5f0eb08759ee763f98daf3b34becb74559Pyry HaulosFunctionalTest13::FunctionalTest13(deqp::Context& context) 658948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos : TestCase(context, "subroutines_with_separate_shader_objects", 659048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "Verifies that subroutines work correctly when used in separate " 659148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "shader objects") 659248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_fbo_id(0) 659348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_pipeline_id(0) 659448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_read_buffer(DE_NULL) 659548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_to_height(4) 659648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_to_id(0) 659748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_to_width(4) 659848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_vao_id(0) 659948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_has_test_passed(true) 660048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 660148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos memset(m_fs_po_ids, 0, sizeof(m_fs_po_ids)); 660248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos memset(m_gs_po_ids, 0, sizeof(m_gs_po_ids)); 660348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos memset(m_tc_po_ids, 0, sizeof(m_tc_po_ids)); 660448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos memset(m_te_po_ids, 0, sizeof(m_te_po_ids)); 660548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos memset(m_vs_po_ids, 0, sizeof(m_vs_po_ids)); 660648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 660748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 660848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Deinitializes all GL objects that may have been created during test 660948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * execution, as well as releases all process-side buffers that may have 661048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * been allocated during the process. 661148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * The function also restores default GL state configuration. 661248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 661348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid FunctionalTest13::deinit() 661448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 661548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 661648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 661748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_fbo_id != 0) 661848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 661948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteFramebuffers(1, &m_fbo_id); 662048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 662148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_fbo_id = 0; 662248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 662348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 662448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_pipeline_id != 0) 662548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 662648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteProgramPipelines(1, &m_pipeline_id); 662748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 662848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_pipeline_id = 0; 662948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 663048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 663148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_read_buffer != DE_NULL) 663248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 663348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos delete[] m_read_buffer; 663448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 663548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_read_buffer = DE_NULL; 663648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 663748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 663848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (unsigned int n_id = 0; n_id < 2 /* po id variants */; ++n_id) 663948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 664048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_fs_po_ids[n_id] != 0) 664148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 664248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteProgram(m_fs_po_ids[n_id]); 664348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 664448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_fs_po_ids[n_id] = 0; 664548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 664648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 664748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_gs_po_ids[n_id] != 0) 664848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 664948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteProgram(m_gs_po_ids[n_id]); 665048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 665148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_gs_po_ids[n_id] = 0; 665248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 665348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 665448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_tc_po_ids[n_id] != 0) 665548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 665648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteProgram(m_tc_po_ids[n_id]); 665748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 665848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_tc_po_ids[n_id] = 0; 665948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 666048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 666148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_te_po_ids[n_id] != 0) 666248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 666348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteProgram(m_te_po_ids[n_id]); 666448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 666548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_te_po_ids[n_id] = 0; 666648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 666748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 666848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_vs_po_ids[n_id] != 0) 666948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 667048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteProgram(m_vs_po_ids[n_id]); 667148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 667248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_vs_po_ids[n_id] = 0; 667348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 667448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } /* for (both shader program object variants) */ 667548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 667648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_to_id != 0) 667748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 667848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteTextures(1, &m_to_id); 667948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 668048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_to_id = 0; 668148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 668248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 668348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_vao_id != 0) 668448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 668548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteVertexArrays(1, &m_vao_id); 668648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 668748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_vao_id = 0; 668848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 668948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 669048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Restore default GL_PATCH_VERTICES setting value */ 669148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.patchParameteri(GL_PATCH_VERTICES, 3); 669248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 669348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Restore default GL_PACK_ALIGNMENT setting value */ 669448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.pixelStorei(GL_PACK_ALIGNMENT, 4); 669548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 669648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 669748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Retrieves body of a fragment shader that should be used for the test. 669848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * The subroutine implementations are slightly changed, depending on the 669948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * index of the shader, as specified by the caller. 670048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 670148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param n_id Index of the shader. 670248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 670348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return Requested string. 670448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 670548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosstd::string FunctionalTest13::getFragmentShaderBody(unsigned int n_id) 670648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 670748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::stringstream result_sstream; 670848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 670948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Pre-amble */ 671048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "#version 400\n" 671148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 671248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "#extension GL_ARB_shader_subroutine : require\n" 671348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 671448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Sub-routine */ 671548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine void SubroutineFSType(inout vec4 result);\n" 671648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 671748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine(SubroutineFSType) void SubroutineFS1(inout vec4 result)\n" 671848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 671948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " result += vec4(" 672048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << float(n_id + 1) / 10.0f << ", " << float(n_id + 2) / 10.0f << ", " << float(n_id + 3) / 10.0f 672148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << ", " << float(n_id + 4) / 10.0f 672248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << ");\n" 672348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 672448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine(SubroutineFSType) void SubroutineFS2(inout vec4 result)\n" 672548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 672648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " result += vec4(" 672748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << float(n_id + 1) / 20.0f << ", " << float(n_id + 2) / 20.0f << ", " << float(n_id + 3) / 20.0f 672848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << ", " << float(n_id + 4) / 20.0f << ");\n" 672948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 673048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 673148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine uniform SubroutineFSType function;\n" 673248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 673348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Input block */ 673448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "in GS_DATA\n" 673548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 673648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " vec4 data;\n" 673748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "} in_gs;\n" 673848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 673948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "out vec4 result;\n" 674048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* main() declaration */ 674148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void main()\n" 674248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 674348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " vec4 data = in_gs.data;\n" 674448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " function(data);\n" 674548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 674648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " result = data;\n" 674748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n"; 674848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 674948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return result_sstream.str(); 675048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 675148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 675248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Retrieves body of a geometry shader that should be used for the test. 675348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * The subroutine implementations are slightly changed, depending on the 675448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * index of the shader, as specified by the caller. 675548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 675648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param n_id Index of the shader. 675748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 675848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return Requested string. 675948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 676048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosstd::string FunctionalTest13::getGeometryShaderBody(unsigned int n_id) 676148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 676248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::stringstream result_sstream; 676348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 676448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Pre-amble */ 676548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "#version 400\n" 676648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 676748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "#extension GL_ARB_shader_subroutine : require\n" 676848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 676948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "layout(points) in;\n" 677048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "layout(triangle_strip, max_vertices = 4) out;\n" 677148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Sub-routine */ 677248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine void SubroutineGSType(inout vec4 result);\n" 677348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 677448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine(SubroutineGSType) void SubroutineGS1(inout vec4 result)\n" 677548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 677648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " result += vec4(0, 0, 0, " 677748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << float(n_id + 1) * 0.425f << ");\n" 677848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 677948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine(SubroutineGSType) void SubroutineGS2(inout vec4 result)\n" 678048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 678148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " result += vec4(0, 0, 0, " 678248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << float(n_id + 1) * 0.0425f << ");\n" 678348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 678448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 678548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine uniform SubroutineGSType function;\n" 678648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 678748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Input block */ 678848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "in TE_DATA\n" 678948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 679048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " vec4 data;\n" 679148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "} in_te[];\n" 679248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 679348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Output block */ 679448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "out GS_DATA\n" 679548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 679648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " vec4 data;\n" 679748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "} out_gs;\n" 679848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 679948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "in gl_PerVertex { vec4 gl_Position; } gl_in[];\n" 680048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "out gl_PerVertex { vec4 gl_Position; };\n" 680148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* main() declaration */ 680248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void main()\n" 680348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 680448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " vec4 data = in_te[0].data;\n" 680548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 680648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " function(data);\n" 680748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 680848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " gl_Position = vec4(1, -1, 0, 1);\n" 680948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " out_gs.data = data;\n" 681048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " EmitVertex();\n" 681148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 681248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " gl_Position = vec4(-1, -1, 0, 1);\n" 681348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " out_gs.data = data;\n" 681448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " EmitVertex();\n" 681548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 681648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " gl_Position = vec4(1, 1, 0, 1);\n" 681748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " out_gs.data = data;\n" 681848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " EmitVertex();\n" 681948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 682048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " gl_Position = vec4(-1, 1, 0, 1);\n" 682148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " out_gs.data = data;\n" 682248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " EmitVertex();\n" 682348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " EndPrimitive();\n" 682448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n"; 682548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 682648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return result_sstream.str(); 682748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 682848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 682948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Retrieves body of a tessellation control shader that should be used for the test. 683048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * The subroutine implementations are slightly changed, depending on the 683148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * index of the shader, as specified by the caller. 683248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 683348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param n_id Index of the shader. 683448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 683548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return Requested string. 683648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 683748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosstd::string FunctionalTest13::getTessellationControlShaderBody(unsigned int n_id) 683848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 683948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::stringstream result_sstream; 684048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 684148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Pre-amble */ 684248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "#version 400\n" 684348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 684448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "#extension GL_ARB_shader_subroutine : require\n" 684548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 684648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "layout(vertices = 4) out;\n" 684748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Sub-routine */ 684848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine void SubroutineTCType(inout vec4 result);\n" 684948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 685048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine(SubroutineTCType) void SubroutineTC1(inout vec4 result)\n" 685148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 685248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " result += vec4(0, " 685348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << float(n_id + 1) * 0.25f << ", 0, 0);\n" 685448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 685548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine(SubroutineTCType) void SubroutineTC2(inout vec4 result)\n" 685648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 685748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " result += vec4(0, " 685848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << float(n_id + 1) * 0.025f 685948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << ", 0, 0);\n" 686048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 686148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 686248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine uniform SubroutineTCType function;\n" 686348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 686448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Input block */ 686548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "in VS_DATA\n" 686648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 686748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " vec4 data;\n" 686848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "} in_vs[];\n" 686948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 687048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Output block */ 687148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "out TC_DATA\n" 687248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 687348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " vec4 data;\n" 687448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "} out_tc[];\n" 687548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 687648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "in gl_PerVertex { vec4 gl_Position; } gl_in[];\n" 687748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "out gl_PerVertex { vec4 gl_Position; } gl_out[];\n" 687848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* main() declaration */ 687948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void main()\n" 688048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 688148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " gl_TessLevelOuter[0] = 1.0;\n" 688248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " gl_TessLevelOuter[1] = 1.0;\n" 688348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " gl_TessLevelOuter[2] = 1.0;\n" 688448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " gl_TessLevelOuter[3] = 1.0;\n" 688548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " gl_TessLevelInner[0] = 1.0;\n" 688648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " gl_TessLevelInner[1] = 1.0;\n" 688709f47ec2b0c267849b8eb6f04571dd42d817fab0Ilia Mirkin " gl_out[gl_InvocationID].gl_Position = gl_in[0].gl_Position;\n" 688848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " out_tc[gl_InvocationID].data = in_vs[0].data;\n" 688948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 689048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " function(out_tc[gl_InvocationID].data);\n" 689148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n"; 689248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 689348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return result_sstream.str(); 689448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 689548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 689648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Retrieves body of a tessellation evaluation shader that should be used for the test. 689748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * The subroutine implementations are slightly changed, depending on the 689848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * index of the shader, as specified by the caller. 689948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 690048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param n_id Index of the shader. 690148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 690248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return Requested string. 690348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 690448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosstd::string FunctionalTest13::getTessellationEvaluationShaderBody(unsigned int n_id) 690548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 690648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::stringstream result_sstream; 690748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 690848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Pre-amble */ 690948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "#version 400\n" 691048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 691148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "#extension GL_ARB_shader_subroutine : require\n" 691248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 691348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "layout(quads, point_mode) in;\n" 691448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Sub-routine */ 691548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine void SubroutineTEType(inout vec4 result);\n" 691648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 691748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine(SubroutineTEType) void SubroutineTE1(inout vec4 result)\n" 691848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 691948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " result += vec4(0, 0, " 692048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << float(n_id + 1) * 0.325f << ", 0);\n" 692148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 692248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine(SubroutineTEType) void SubroutineTE2(inout vec4 result)\n" 692348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 692448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " result += vec4(0, 0, " 692548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << float(n_id + 1) * 0.0325f << ", 0);\n" 692648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 692748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 692848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine uniform SubroutineTEType function;\n" 692948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 693048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Input block */ 693148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "in TC_DATA\n" 693248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 693348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " vec4 data;\n" 693448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "} in_tc[];\n" 693548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 693648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Output block */ 693748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "out TE_DATA\n" 693848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 693948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " vec4 data;\n" 694048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "} out_te;\n" 694148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 694248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "in gl_PerVertex { vec4 gl_Position; } gl_in[];\n" 694348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "out gl_PerVertex { vec4 gl_Position; };\n" 694448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* main() declaration */ 694548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void main()\n" 694648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 694748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " gl_Position = gl_in[0].gl_Position;\n" 694848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " out_te.data = in_tc[0].data;\n" 694948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 695048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " function(out_te.data);\n" 695148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n"; 695248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 695348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return result_sstream.str(); 695448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 695548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 695648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Retrieves body of a vertex shader that should be used for the test. 695748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * The subroutine implementations are slightly changed, depending on the 695848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * index of the shader, as specified by the caller. 695948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 696048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param n_id Index of the shader. 696148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 696248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return Requested string. 696348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 696448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosstd::string FunctionalTest13::getVertexShaderBody(unsigned int n_id) 696548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 696648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::stringstream result_sstream; 696748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 696848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Pre-amble */ 696948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "#version 400\n" 697048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 697148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "#extension GL_ARB_shader_subroutine : require\n" 697248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 697348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Sub-routine */ 697448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine void SubroutineVSType(inout vec4 result);\n" 697548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 697648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine(SubroutineVSType) void SubroutineVS1(inout vec4 result)\n" 697748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 697848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " result += vec4(" 697948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << float(n_id + 1) * 0.125f << ", 0, 0, 0);\n" 698048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 698148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine(SubroutineVSType) void SubroutineVS2(inout vec4 result)\n" 698248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 698348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " result += vec4(" 698448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << float(n_id + 1) * 0.0125f << ", 0, 0, 0);\n" 698548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 698648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 698748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine uniform SubroutineVSType function;\n" 698848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 698948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Output block */ 699048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "out VS_DATA\n" 699148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 699248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " vec4 data;\n" 699348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "} out_vs;\n" 699448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 699548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "out gl_PerVertex { vec4 gl_Position; };\n" 699648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* main() declaration */ 699748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void main()\n" 699848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 699948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " gl_Position = vec4(0, 0, 0, 1);\n" 700048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " out_vs.data = vec4(0);\n" 700148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 700248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " function(out_vs.data);\n" 700348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 700448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n"; 700548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 700648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return result_sstream.str(); 700748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 700848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 700948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Initializes all GL objects required to run the test. Also modifies a few 701048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * GL states in order for the test to run correctly. 701148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 701248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid FunctionalTest13::initTest() 701348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 701448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 701548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 701648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Set up viewport */ 701748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.viewport(0 /* x */, 0 /* y */, m_to_width, m_to_height); 701848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport() call failed."); 701948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 702048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Make sure no program is used */ 702148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.useProgram(0); 702248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed."); 702348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 702448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Generate a pipeline object */ 702548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.genProgramPipelines(1, &m_pipeline_id); 702648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glGenProgramPipelines() call failed."); 702748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 702848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.bindProgramPipeline(m_pipeline_id); 702948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glBindProgramPipeline() call failed."); 703048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 703148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Initialize all shader programs */ 703248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (unsigned int n_id = 0; n_id < 2 /* variants for each shader type */; ++n_id) 703348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 703448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::string fs_body = getFragmentShaderBody(n_id); 703548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* fs_body_raw_ptr = fs_body.c_str(); 703648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::string gs_body = getGeometryShaderBody(n_id); 703748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* gs_body_raw_ptr = gs_body.c_str(); 703848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::string tc_body = getTessellationControlShaderBody(n_id); 703948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* tc_body_raw_ptr = tc_body.c_str(); 704048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::string te_body = getTessellationEvaluationShaderBody(n_id); 704148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* te_body_raw_ptr = te_body.c_str(); 704248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::string vs_body = getVertexShaderBody(n_id); 704348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* vs_body_raw_ptr = vs_body.c_str(); 704448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 704548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_fs_po_ids[n_id] = gl.createShaderProgramv(GL_FRAGMENT_SHADER, 1 /* count */, &fs_body_raw_ptr); 704648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShaderProgramv() call failed."); 704748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 704848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_gs_po_ids[n_id] = gl.createShaderProgramv(GL_GEOMETRY_SHADER, 1 /* count */, &gs_body_raw_ptr); 704948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShaderProgramv() call failed."); 705048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 705148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_tc_po_ids[n_id] = gl.createShaderProgramv(GL_TESS_CONTROL_SHADER, 1 /* count */, &tc_body_raw_ptr); 705248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShaderProgramv() call failed."); 705348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 705448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_te_po_ids[n_id] = gl.createShaderProgramv(GL_TESS_EVALUATION_SHADER, 1 /* count */, &te_body_raw_ptr); 705548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShaderProgramv() call failed."); 705648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 705748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_vs_po_ids[n_id] = gl.createShaderProgramv(GL_VERTEX_SHADER, 1 /* count */, &vs_body_raw_ptr); 705848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShaderProgramv() call failed."); 705948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 706048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Verify that all shader program objects have been linked successfully */ 706148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::GLuint po_ids[] = { 706248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_fs_po_ids[n_id], m_gs_po_ids[n_id], m_tc_po_ids[n_id], m_te_po_ids[n_id], m_vs_po_ids[n_id], 706348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos }; 706448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const unsigned int n_po_ids = sizeof(po_ids) / sizeof(po_ids[0]); 706548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 706648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (unsigned int n_po_id = 0; n_po_id < n_po_ids; ++n_po_id) 706748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 706848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glw::GLint link_status = GL_FALSE; 706948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glw::GLuint po_id = po_ids[n_po_id]; 707048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 707148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getProgramiv(po_id, GL_LINK_STATUS, &link_status); 707248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv() call failed."); 707348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 707448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (link_status != GL_TRUE) 707548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 707648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos TCU_FAIL("Shader program object linking failed."); 707748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 707848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } /* for (all shader program objects) */ 707948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } /* for (both shader program object variants) */ 708048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 708148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Generate a texture object. We will use the base mip-map as a render-target */ 708248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.genTextures(1, &m_to_id); 708348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() call failed."); 708448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 708548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.bindTexture(GL_TEXTURE_2D, m_to_id); 708648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed."); 708748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 708848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.texStorage2D(GL_TEXTURE_2D, 1 /* levels */, GL_RGBA32F, m_to_width, m_to_height); 708948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2D() call failed"); 709048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 709148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Generate and configure a FBO we will use for the draw call */ 709248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.genFramebuffers(1, &m_fbo_id); 709348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers() call failed."); 709448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 709548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_id); 709648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer() call failed."); 709748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 709848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.framebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_to_id, 0 /* level */); 709948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture2D() call failed."); 710048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 710148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Generate & bind a VAO */ 710248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.genVertexArrays(1, &m_vao_id); 710348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays() call failed."); 710448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 710548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.bindVertexArray(m_vao_id); 710648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() call failed."); 710748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 710848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Set up tessellation */ 710948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.patchParameteri(GL_PATCH_VERTICES, 1); 711048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glPatchParameteri() call failed."); 711148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 711248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Set up pixel storage alignment */ 711348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.pixelStorei(GL_PACK_ALIGNMENT, 1); 711448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glPixelStorei() call failed."); 711548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 711648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Allocate enough space to hold color attachment data */ 711748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_read_buffer = (unsigned char*)new float[m_to_width * m_to_height * 4 /* rgba */]; 711848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 711948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 712048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Executes test iteration. 712148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 712248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed. 712348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos */ 712448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulostcu::TestNode::IterateResult FunctionalTest13::iterate() 712548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 712648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 712748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 712848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Do not execute the test if GL_ARB_shader_subroutine and GL_ARB_separate_shader_objects 712948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * are not supported */ 713048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_shader_subroutine")) 713148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 713248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos throw tcu::NotSupportedError("GL_ARB_shader_subroutine is not supported."); 713348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 713448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 713548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_separate_shader_objects")) 713648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 713748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos throw tcu::NotSupportedError("GL_ARB_separate_shader_objects is not supported"); 713848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 713948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 714048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Initialize all GL objects before we continue */ 714148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos initTest(); 714248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 714348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Iterate over all possible FS/GS/TC/TE/VS permutations */ 714448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (int n_shader_permutation = 0; n_shader_permutation < 32 /* 2^5 */; ++n_shader_permutation) 714548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 714648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const unsigned int n_fs_idx = ((n_shader_permutation & (1 << 0)) != 0) ? 1 : 0; 714748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const unsigned int n_gs_idx = ((n_shader_permutation & (1 << 1)) != 0) ? 1 : 0; 714848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const unsigned int n_tc_idx = ((n_shader_permutation & (1 << 2)) != 0) ? 1 : 0; 714948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const unsigned int n_te_idx = ((n_shader_permutation & (1 << 3)) != 0) ? 1 : 0; 715048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const unsigned int n_vs_idx = ((n_shader_permutation & (1 << 4)) != 0) ? 1 : 0; 715148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const unsigned int fs_po_id = m_fs_po_ids[n_fs_idx]; 715248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const unsigned int gs_po_id = m_gs_po_ids[n_gs_idx]; 715348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const unsigned int tc_po_id = m_tc_po_ids[n_tc_idx]; 715448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const unsigned int te_po_id = m_te_po_ids[n_te_idx]; 715548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const unsigned int vs_po_id = m_vs_po_ids[n_vs_idx]; 715648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 715748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Configure fragment shader stage */ 715848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.useProgramStages(m_pipeline_id, GL_FRAGMENT_SHADER_BIT, fs_po_id); 715948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgramStages() call failed for GL_FRAGMENT_SHADER_BIT bit"); 716048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 716148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Configure geometry shader stage */ 716248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.useProgramStages(m_pipeline_id, GL_GEOMETRY_SHADER_BIT, gs_po_id); 716348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgramStages() call failed for GL_GEOMETRY_SHADER_BIT bit"); 716448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 716548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Configure tessellation control shader stage */ 716648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.useProgramStages(m_pipeline_id, GL_TESS_CONTROL_SHADER_BIT, tc_po_id); 716748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgramStages() call failed for GL_TESS_CONTROL_SHADER_BIT bit"); 716848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 716948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Configure tessellation evaluation shader stage */ 717048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.useProgramStages(m_pipeline_id, GL_TESS_EVALUATION_SHADER_BIT, te_po_id); 717148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgramStages() call failed for GL_TESS_EVALUATION_SHADER_BIT bit"); 717248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 717348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Configure vertex shader stage */ 717448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.useProgramStages(m_pipeline_id, GL_VERTEX_SHADER_BIT, vs_po_id); 717548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgramStages() call failed for GL_VERTEX_SHADER_BIT bit"); 717648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 717748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Validate the pipeline */ 717848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glw::GLint validate_status = GL_FALSE; 717948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 718048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.validateProgramPipeline(m_pipeline_id); 718148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glValidateProgramPipeline() call failed."); 718248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 718348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getProgramPipelineiv(m_pipeline_id, GL_VALIDATE_STATUS, &validate_status); 718448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramPipelineiv() call failed."); 718548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 718648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (validate_status != GL_TRUE) 718748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 718848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos TCU_FAIL("Program pipeline has not been validated successfully."); 718948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 719048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 719148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Retrieve subroutine indices */ 719248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint fs_subroutine_indices[2] = { (GLuint)-1 }; 719348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLint fs_subroutine_uniform_index = 0; 719448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint gs_subroutine_indices[2] = { (GLuint)-1 }; 719548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLint gs_subroutine_uniform_index = 0; 719648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint tc_subroutine_indices[2] = { (GLuint)-1 }; 719748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLint tc_subroutine_uniform_index = 0; 719848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint te_subroutine_indices[2] = { (GLuint)-1 }; 719948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLint te_subroutine_uniform_index = 0; 720048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint vs_subroutine_indices[2] = { (GLuint)-1 }; 720148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLint vs_subroutine_uniform_index = 0; 720248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 720348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (unsigned int n_subroutine = 0; n_subroutine < 2; ++n_subroutine) 720448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 720548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::stringstream fs_subroutine_name_sstream; 720648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::stringstream gs_subroutine_name_sstream; 720748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::stringstream tc_subroutine_name_sstream; 720848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::stringstream te_subroutine_name_sstream; 720948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::stringstream vs_subroutine_name_sstream; 721048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 721148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos fs_subroutine_name_sstream << "SubroutineFS" << (n_subroutine + 1); 721248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gs_subroutine_name_sstream << "SubroutineGS" << (n_subroutine + 1); 721348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos tc_subroutine_name_sstream << "SubroutineTC" << (n_subroutine + 1); 721448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos te_subroutine_name_sstream << "SubroutineTE" << (n_subroutine + 1); 721548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos vs_subroutine_name_sstream << "SubroutineVS" << (n_subroutine + 1); 721648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 721748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos fs_subroutine_indices[n_subroutine] = 721848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getSubroutineIndex(fs_po_id, GL_FRAGMENT_SHADER, fs_subroutine_name_sstream.str().c_str()); 721948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gs_subroutine_indices[n_subroutine] = 722048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getSubroutineIndex(gs_po_id, GL_GEOMETRY_SHADER, gs_subroutine_name_sstream.str().c_str()); 722148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos tc_subroutine_indices[n_subroutine] = 722248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getSubroutineIndex(tc_po_id, GL_TESS_CONTROL_SHADER, tc_subroutine_name_sstream.str().c_str()); 722348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos te_subroutine_indices[n_subroutine] = 722448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getSubroutineIndex(te_po_id, GL_TESS_EVALUATION_SHADER, te_subroutine_name_sstream.str().c_str()); 722548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos vs_subroutine_indices[n_subroutine] = 722648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getSubroutineIndex(vs_po_id, GL_VERTEX_SHADER, vs_subroutine_name_sstream.str().c_str()); 722748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glGetSubroutineIndex() call(s) failed."); 722848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 722948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (fs_subroutine_indices[n_subroutine] == (GLuint)-1 || 723048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gs_subroutine_indices[n_subroutine] == (GLuint)-1 || 723148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos tc_subroutine_indices[n_subroutine] == (GLuint)-1 || 723248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos te_subroutine_indices[n_subroutine] == (GLuint)-1 || vs_subroutine_indices[n_subroutine] == (GLuint)-1) 723348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 723448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.getLog() << tcu::TestLog::Message 723548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << "At least one subroutine was not recognized by glGetSubroutineIndex() call. " 723648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "(fs:" 723748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << fs_subroutine_indices[n_subroutine] 723848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << ", gs:" << gs_subroutine_indices[n_subroutine] 723948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << ", tc:" << tc_subroutine_indices[n_subroutine] 724048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << ", te:" << te_subroutine_indices[n_subroutine] 724148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << ", vs:" << vs_subroutine_indices[n_subroutine] << ")." 724248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << tcu::TestLog::EndMessage; 724348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 724448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos TCU_FAIL("At least one subroutine was not recognized"); 724548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 724648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } /* for (both subroutines) */ 724748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 724848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Retrieve subroutine uniform indices */ 724948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos fs_subroutine_uniform_index = gl.getSubroutineUniformLocation(fs_po_id, GL_FRAGMENT_SHADER, "function"); 725048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gs_subroutine_uniform_index = gl.getSubroutineUniformLocation(gs_po_id, GL_GEOMETRY_SHADER, "function"); 725148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos tc_subroutine_uniform_index = gl.getSubroutineUniformLocation(tc_po_id, GL_TESS_CONTROL_SHADER, "function"); 725248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos te_subroutine_uniform_index = gl.getSubroutineUniformLocation(te_po_id, GL_TESS_EVALUATION_SHADER, "function"); 725348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos vs_subroutine_uniform_index = gl.getSubroutineUniformLocation(vs_po_id, GL_VERTEX_SHADER, "function"); 725448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 725548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (fs_subroutine_uniform_index == -1 || gs_subroutine_uniform_index == -1 || 725648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos tc_subroutine_uniform_index == -1 || te_subroutine_uniform_index == -1 || vs_subroutine_uniform_index == -1) 725748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 725848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.getLog() << tcu::TestLog::Message << "At least one subroutine uniform is considered inactive by " 725948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "glGetSubroutineUniformLocation (" 726048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "fs:" 726148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << fs_subroutine_uniform_index << ", gs:" << gs_subroutine_uniform_index 726248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << ", tc:" << tc_subroutine_uniform_index << ", te:" << te_subroutine_uniform_index 726348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << ", vs:" << vs_subroutine_uniform_index << ")." << tcu::TestLog::EndMessage; 726448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 726548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos TCU_FAIL("At least one subroutine uniform is considered inactive"); 726648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 726748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 726848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Check if both subroutines work correctly in each stage */ 726948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (int n_subroutine_permutation = 0; n_subroutine_permutation < 32; /* 2^5 */ 727048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos ++n_subroutine_permutation) 727148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 727248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos unsigned int n_fs_subroutine = ((n_subroutine_permutation & (1 << 0)) != 0) ? 1 : 0; 727348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos unsigned int n_gs_subroutine = ((n_subroutine_permutation & (1 << 1)) != 0) ? 1 : 0; 727448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos unsigned int n_tc_subroutine = ((n_subroutine_permutation & (1 << 2)) != 0) ? 1 : 0; 727548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos unsigned int n_te_subroutine = ((n_subroutine_permutation & (1 << 3)) != 0) ? 1 : 0; 727648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos unsigned int n_vs_subroutine = ((n_subroutine_permutation & (1 << 4)) != 0) ? 1 : 0; 727748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 727848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Configure subroutine uniforms */ 727948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos struct 728048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 728148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glw::GLenum stage; 728248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glw::GLuint po_id; 728348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glw::GLuint* indices; 728448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } configurations[] = { 728548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { GL_FRAGMENT_SHADER, fs_po_id, fs_subroutine_indices + n_fs_subroutine }, 728648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { GL_GEOMETRY_SHADER, gs_po_id, gs_subroutine_indices + n_gs_subroutine }, 728748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { GL_TESS_CONTROL_SHADER, tc_po_id, tc_subroutine_indices + n_tc_subroutine }, 728848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { GL_TESS_EVALUATION_SHADER, te_po_id, te_subroutine_indices + n_te_subroutine }, 728948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { GL_VERTEX_SHADER, vs_po_id, vs_subroutine_indices + n_vs_subroutine }, 729048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos }; 729148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 729248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (int i = 0; i < 5; ++i) 729348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 729448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.activeShaderProgram(m_pipeline_id, configurations[i].po_id); 729548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glActiveShaderProgram() call failed."); 729648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 729748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.uniformSubroutinesuiv(configurations[i].stage, 1 /* count */, configurations[i].indices); 729848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glUniformSubroutinesuiv() call failed."); 729948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 730048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 730148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Render a full-screen quad with the pipeline */ 730248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.clear(GL_COLOR_BUFFER_BIT); 730348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glClear() call failed."); 730448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 730548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.drawArrays(GL_PATCHES, 0 /* first */, 1 /* count */); 730648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() call failed."); 730748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 730848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Read color attachment's contents */ 730948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.readPixels(0, /* x */ 731048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 0, /* y */ 731148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_to_width, m_to_height, GL_RGBA, GL_FLOAT, m_read_buffer); 731248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels() call failed."); 731348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 731448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Verify the contents */ 731548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos verifyReadBuffer(n_fs_idx, n_fs_subroutine, n_gs_idx, n_gs_subroutine, n_tc_idx, n_tc_subroutine, n_te_idx, 731648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos n_te_subroutine, n_vs_idx, n_vs_subroutine); 731748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } /* for (all subroutine permutations) */ 731848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } /* for (all program shader object permutations) */ 731948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 732048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /** All done */ 732148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_has_test_passed) 732248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 732348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 732448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 732548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else 732648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 732748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 732848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 732948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 733048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return STOP; 733148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 733248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 733348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Verifies the data that have been rendered using a pipeline object. 733448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * Contents of the data depends on indices of the shaders, as well as 733548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * on the subroutines that have been activated for particular iteration. 733648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 733748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param n_fs_id Index of the fragment shader used for the iteration; 733848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param n_fs_subroutine Index of the subroutine used in the fragment shader 733948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * for the iteration; 734048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param n_gs_id Index of the geometry shader used for the iteration; 734148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param n_gs_subroutine Index of the subroutine used in the geometry shader 734248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * for the iteration; 734348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param n_tc_id Index of the tessellation control shader used for the iteration; 734448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param n_tc_subroutine Index of the subroutine used in the tessellation control 734548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * shader for the iteration; 734648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param n_te_id Index of the tessellation evaluation shader used for the iteration; 734748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param n_te_subroutine Index of the subroutine used in the tessellation evaluation 734848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * shader for the iteration; 734948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param n_vs_id Index of the vertex shader used for the iteration; 735048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param n_vs_subroutine Index of the subroutine used in the vertex shader for 735148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * the iteration. 735248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos */ 735348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid FunctionalTest13::verifyReadBuffer(unsigned int n_fs_id, unsigned int n_fs_subroutine, unsigned int n_gs_id, 735448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos unsigned int n_gs_subroutine, unsigned int n_tc_id, 735548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos unsigned int n_tc_subroutine, unsigned int n_te_id, 735648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos unsigned int n_te_subroutine, unsigned int n_vs_id, 735748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos unsigned int n_vs_subroutine) 735848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 735948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos float expected_color[4] = { 0 }; 736048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos float fs_modifier[4] = { 0 }; 736148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos float gs_modifier[4] = { 0 }; 736248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos float tc_modifier[4] = { 0 }; 736348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos float te_modifier[4] = { 0 }; 736448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos float vs_modifier[4] = { 0 }; 736548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 736648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (n_fs_subroutine == 0) 736748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 736848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (unsigned int n_component = 0; n_component < 4; ++n_component) 736948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 737048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos fs_modifier[n_component] = float(n_fs_id + n_component + 1) / 10.0f; 737148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 737248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 737348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else 737448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 737548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (unsigned int n_component = 0; n_component < 4; ++n_component) 737648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 737748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos fs_modifier[n_component] = float(n_fs_id + n_component + 1) / 20.0f; 737848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 737948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 738048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 738148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (n_gs_subroutine == 0) 738248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 738348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gs_modifier[3] = float(n_gs_id + 1) * 0.425f; 738448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 738548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else 738648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 738748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gs_modifier[3] = float(n_gs_id + 1) * 0.0425f; 738848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 738948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 739048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (n_tc_subroutine == 0) 739148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 739248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos tc_modifier[1] = float(n_tc_id + 1) * 0.25f; 739348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 739448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else 739548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 739648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos tc_modifier[1] = float(n_tc_id + 1) * 0.025f; 739748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 739848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 739948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (n_te_subroutine == 0) 740048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 740148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos te_modifier[2] = float(n_te_id + 1) * 0.325f; 740248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 740348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else 740448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 740548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos te_modifier[2] = float(n_te_id + 1) * 0.0325f; 740648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 740748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 740848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (n_vs_subroutine == 0) 740948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 741048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos vs_modifier[0] = float(n_vs_id + 1) * 0.125f; 741148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 741248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else 741348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 741448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos vs_modifier[0] = float(n_vs_id + 1) * 0.0125f; 741548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 741648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 741748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Determine the expected color */ 741848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (unsigned int n_component = 0; n_component < 4 /* rgba */; ++n_component) 741948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 742048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos expected_color[n_component] = fs_modifier[n_component] + gs_modifier[n_component] + tc_modifier[n_component] + 742148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos te_modifier[n_component] + vs_modifier[n_component]; 742248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 742348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 742448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Verify all read texels are valid */ 742548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const float epsilon = 1e-5f; 742648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos bool should_continue = true; 742748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 742848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (unsigned int y = 0; y < m_to_height && should_continue; ++y) 742948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 743048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const float* row_ptr = (const float*)m_read_buffer + y * m_to_width * 4; /* rgba */ 743148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 743248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (unsigned int x = 0; x < m_to_width && should_continue; ++x) 743348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 743448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const float* texel_ptr = row_ptr + x * 4; /* rgba */ 743548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 743648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (de::abs(texel_ptr[0] - expected_color[0]) > epsilon || 743748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos de::abs(texel_ptr[1] - expected_color[1]) > epsilon || 743848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos de::abs(texel_ptr[2] - expected_color[2]) > epsilon || 743948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos de::abs(texel_ptr[3] - expected_color[3]) > epsilon) 744048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 744148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.getLog() << tcu::TestLog::Message << "Invalid texel rendered at (" << x << ", " << y 744248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << ") for " 744348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "the following configuration: " 744448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "n_fs_id:" 744548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << n_fs_id << " n_fs_subroutine:" << n_fs_subroutine << " n_gs_id:" << n_gs_id 744648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << " n_gs_subroutine:" << n_gs_subroutine << " n_tc_id:" << n_tc_id 744748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << " n_tc_subroutine:" << n_tc_subroutine << " n_te_id:" << n_te_id 744848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << " n_te_subroutine:" << n_te_subroutine << " n_vs_id:" << n_vs_id 744948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << " n_vs_subroutine:" << n_vs_subroutine << "; expected:" 745048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "(" 745148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << expected_color[0] << ", " << expected_color[1] << ", " << expected_color[2] 745248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << ", " << expected_color[3] << "), found:" 745348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "(" 745448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << texel_ptr[0] << ", " << texel_ptr[1] << ", " << texel_ptr[2] << ", " 745548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << texel_ptr[3] << ")." << tcu::TestLog::EndMessage; 745648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 745748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_has_test_passed = false; 745848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos should_continue = false; 745948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 746048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } /* for (all columns) */ 746148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } /* for (all rows) */ 746248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 746348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 746448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Constructor 746548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 746648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param context CTS context 746748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 746848087f5f0eb08759ee763f98daf3b34becb74559Pyry HaulosFunctionalTest14_15::FunctionalTest14_15(deqp::Context& context) 746948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos : TestCase(context, "structure_parameters_program_binary", "Verify structures can be used as parameters") 747048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_uniform_location(0) 747148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 747248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 747348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 747448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Execute test 747548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 747648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return tcu::TestNode::STOP 747748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 747848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulostcu::TestNode::IterateResult FunctionalTest14_15::iterate() 747948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 748048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLchar* vertex_shader_code = 748148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "#version 400 core\n" 748248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "#extension GL_ARB_shader_subroutine : require\n" 748348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 748448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "precision highp float;\n" 748548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 748648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "struct data\n" 748748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 748848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " uint r;\n" 748948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " uint g;\n" 749048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " uint b;\n" 749148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " uint a;\n" 749248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "};\n" 749348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 749448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine void routine_type_1(in data iparam, out data oparam);\n" 749548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine void routine_type_2(inout data arg);\n" 749648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 749748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine (routine_type_1) void invert(in data iparam, out data oparam)\n" 749848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 749948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " oparam.r = iparam.a;\n" 750048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " oparam.g = iparam.b;\n" 750148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " oparam.b = iparam.g;\n" 750248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " oparam.a = iparam.r;\n" 750348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 750448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 750548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine (routine_type_1) void increment(in data iparam, out data oparam)\n" 750648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 750748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " oparam.r = 1 + iparam.r;\n" 750848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " oparam.g = 1 + iparam.g;\n" 750948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " oparam.b = 1 + iparam.b;\n" 751048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " oparam.a = 1 + iparam.a;\n" 751148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 751248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 751348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine (routine_type_2) void div_by_2(inout data arg)\n" 751448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 751548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " arg.r = arg.r / 2;\n" 751648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " arg.g = arg.g / 2;\n" 751748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " arg.b = arg.b / 2;\n" 751848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " arg.a = arg.a / 2;\n" 751948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 752048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 752148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine (routine_type_2) void decrement(inout data arg)\n" 752248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 752348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " arg.r = arg.r - 1;\n" 752448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " arg.g = arg.g - 1;\n" 752548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " arg.b = arg.b - 1;\n" 752648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " arg.a = arg.a - 1;\n" 752748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 752848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 752948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine uniform routine_type_1 routine_1;\n" 753048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine uniform routine_type_2 routine_2;\n" 753148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 753248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "uniform uvec4 uni_input;\n" 753348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 753448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "out uvec4 out_routine_1;\n" 753548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "out uvec4 out_routine_2;\n" 753648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 753748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 753848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void main()\n" 753948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 754048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " data routine_1_input;\n" 754148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " data routine_1_output;\n" 754248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " data routine_2_arg;\n" 754348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 754448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " routine_1_input.r = uni_input.r;\n" 754548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " routine_1_input.g = uni_input.g;\n" 754648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " routine_1_input.b = uni_input.b;\n" 754748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " routine_1_input.a = uni_input.a;\n" 754848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 754948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " routine_2_arg.r = uni_input.r;\n" 755048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " routine_2_arg.g = uni_input.g;\n" 755148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " routine_2_arg.b = uni_input.b;\n" 755248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " routine_2_arg.a = uni_input.a;\n" 755348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 755448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " routine_1(routine_1_input, routine_1_output);\n" 755548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " routine_2(routine_2_arg);\n" 755648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 755748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " out_routine_1.r = routine_1_output.r;\n" 755848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " out_routine_1.g = routine_1_output.g;\n" 755948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " out_routine_1.b = routine_1_output.b;\n" 756048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " out_routine_1.a = routine_1_output.a;\n" 756148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 756248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " out_routine_2.r = routine_2_arg.r;\n" 756348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " out_routine_2.g = routine_2_arg.g;\n" 756448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " out_routine_2.b = routine_2_arg.b;\n" 756548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " out_routine_2.a = routine_2_arg.a;\n" 756648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 756748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n"; 756848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 756948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLchar* subroutine_names[][2] = { { "invert", "increment" }, { "div_by_2", "decrement" } }; 757048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLuint n_subroutine_types = sizeof(subroutine_names) / sizeof(subroutine_names[0]); 757148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 757248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLchar* subroutine_uniform_names[] = { "routine_1", "routine_2" }; 757348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLuint n_subroutine_uniform_names = 757448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos sizeof(subroutine_uniform_names) / sizeof(subroutine_uniform_names[0]); 757548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 757648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLchar* uniform_name = "uni_input"; 757748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLchar* varying_names[] = { "out_routine_1", "out_routine_2" }; 757848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 757948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLuint n_varying_names = sizeof(varying_names) / sizeof(varying_names[0]); 758048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLuint transform_feedback_buffer_size = n_varying_names * 4 * sizeof(GLuint); 758148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 758248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Test data */ 758348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const Utils::vec4<GLuint> uni_input[] = { Utils::vec4<GLuint>(8, 64, 4096, 16777216), 758448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::vec4<GLuint>(8, 64, 4096, 16777216) }; 758548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 758648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const Utils::vec4<GLuint> out_routine_1[] = { Utils::vec4<GLuint>(16777216, 4096, 64, 8), 758748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::vec4<GLuint>(9, 65, 4097, 16777217) }; 758848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 758948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const Utils::vec4<GLuint> out_routine_2[] = { Utils::vec4<GLuint>(4, 32, 2048, 8388608), 759048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::vec4<GLuint>(7, 63, 4095, 16777215) }; 759148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 759248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLuint n_test_cases = 2; 759348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 759448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Do not execute the test if GL_ARB_shader_subroutine is not supported */ 759548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_shader_subroutine")) 759648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 759748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos throw tcu::NotSupportedError("GL_ARB_shader_subroutine is not supported."); 759848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 759948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 760048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* GL objects */ 760148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::program program(m_context); 760248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::buffer transform_feedback_buffer(m_context); 760348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::vertexArray vao(m_context); 760448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 760548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos bool is_program_binary_supported = program.isProgramBinarySupported(); 760648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 760748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Init GL objects */ 760848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos program.build(0 /* cs */, 0 /* fs */, 0 /* gs */, 0 /* tcs */, 0 /* test */, vertex_shader_code, 760948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos varying_names /* varying_names */, n_varying_names /* n_varyings */); 761048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 761148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Do not execute the test if GL_ARB_get_program_binary is not supported */ 761248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (true == is_program_binary_supported) 761348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 761448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Get subroutine indices */ 761548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLuint type = 0; type < n_subroutine_types; ++type) 761648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 761748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_initial_subroutine_indices[type][0] = 761848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos program.getSubroutineIndex(subroutine_names[type][0], GL_VERTEX_SHADER); 761948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 762048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_initial_subroutine_indices[type][1] = 762148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos program.getSubroutineIndex(subroutine_names[type][1], GL_VERTEX_SHADER); 762248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 762348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 762448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Get subroutine uniform locations */ 762548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLuint uniform = 0; uniform < n_subroutine_uniform_names; ++uniform) 762648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 762748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_initial_subroutine_uniform_locations[uniform] = 762848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos program.getSubroutineUniformLocation(subroutine_uniform_names[uniform], GL_VERTEX_SHADER); 762948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 763048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 763148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Delete program and recreate it from binary */ 763248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::vector<GLubyte> program_binary; 763348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLenum binary_format; 763448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 763548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos program.getBinary(program_binary, binary_format); 763648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos program.remove(); 763748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos program.createFromBinary(program_binary, binary_format); 763848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 763948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 764048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos program.use(); 764148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 764248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos vao.generate(); 764348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos vao.bind(); 764448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 764548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos transform_feedback_buffer.generate(); 764648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos transform_feedback_buffer.update(GL_TRANSFORM_FEEDBACK_BUFFER, transform_feedback_buffer_size, 0 /* data */, 764748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GL_DYNAMIC_COPY); 764848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos transform_feedback_buffer.bindRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, 0, transform_feedback_buffer_size); 764948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 765048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Get subroutine indices */ 765148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLuint type = 0; type < n_subroutine_types; ++type) 765248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 765348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_subroutine_indices[type][0] = program.getSubroutineIndex(subroutine_names[type][0], GL_VERTEX_SHADER); 765448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_subroutine_indices[type][1] = program.getSubroutineIndex(subroutine_names[type][1], GL_VERTEX_SHADER); 765548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 765648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 765748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Get subroutine uniform locations */ 765848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLuint uniform = 0; uniform < n_subroutine_uniform_names; ++uniform) 765948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 766048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_subroutine_uniform_locations[uniform] = 766148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos program.getSubroutineUniformLocation(subroutine_uniform_names[uniform], GL_VERTEX_SHADER); 766248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 766348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 766448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Get uniform locations */ 766548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_uniform_location = program.getUniformLocation(uniform_name); 766648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 766748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Test */ 766848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos bool result = true; 766948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 767048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Test program binary */ 767148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (true == is_program_binary_supported) 767248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 767348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Test indices and locations */ 767448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (false == testIndicesAndLocations()) 767548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 767648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLuint n_subroutines_per_type = 2; 767748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 767848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_context.getTestContext().getLog() << tcu::TestLog::Message 767948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << "Error. Subroutine indices or subroutine uniform location changed." 768048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << tcu::TestLog::EndMessage; 768148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 768248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLuint type = 0; type < n_subroutine_types; ++type) 768348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 768448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLuint i = 0; i < n_subroutines_per_type; ++i) 768548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 768648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_context.getTestContext().getLog() 768748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << tcu::TestLog::Message << "Subroutine: " << subroutine_names[type][i] 768848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << " index: " << m_subroutine_indices[type][i] 768948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << " initial index: " << m_initial_subroutine_indices[type][i] << tcu::TestLog::EndMessage; 769048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 769148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 769248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 769348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLuint uniform = 0; uniform < n_subroutine_uniform_names; ++uniform) 769448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 769548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_context.getTestContext().getLog() 769648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << tcu::TestLog::Message << "Subroutine uniform: " << subroutine_uniform_names[uniform] 769748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << " location: " << m_subroutine_uniform_locations[uniform] 769848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << " initial location: " << m_initial_subroutine_uniform_locations[uniform] 769948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << tcu::TestLog::EndMessage; 770048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 770148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 770248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = false; 770348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 770448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 770548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Test draw with deafult set of subroutines */ 770648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (false == testDefaultSubroutineSet(uni_input[0], out_routine_1, out_routine_2)) 770748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 770848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = false; 770948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 771048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 771148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 771248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLuint i = 0; i < n_test_cases; ++i) 771348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 771448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (false == testDraw(i, uni_input[i], out_routine_1[i], out_routine_2[i])) 771548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 771648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = false; 771748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 771848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 771948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 772048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Set result */ 772148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (true == result) 772248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 772348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 772448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 772548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else 772648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 772748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 772848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 772948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 773048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Done */ 773148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return tcu::TestNode::STOP; 773248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 773348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 773448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Execute draw call and verify results 773548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 773648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param uni_input Input data 773748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param expected_routine_1_result Set of expected results of "routine_1" 773848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param expected_routine_2_result Set of expected results of "routine_2" 773948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 774048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return true if test pass, false otherwise 774148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 774248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosbool FunctionalTest14_15::testDefaultSubroutineSet(const Utils::vec4<glw::GLuint>& uni_input, 774348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const Utils::vec4<glw::GLuint> expected_routine_1_result[2], 774448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const Utils::vec4<glw::GLuint> expected_routine_2_result[2]) const 774548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 774648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 774748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos bool result = true; 774848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 774948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Set up input data uniforms */ 775048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.uniform4ui(m_uniform_location, uni_input.m_x, uni_input.m_y, uni_input.m_z, uni_input.m_w); 775148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "Uniform4f"); 775248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 775348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Execute draw call with transform feedback */ 775448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.beginTransformFeedback(GL_POINTS); 775548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback"); 775648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 775748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.drawArrays(GL_POINTS, 0 /* first */, 1 /* count */); 775848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays"); 775948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 776048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.endTransformFeedback(); 776148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback"); 776248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 776348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Capture results */ 776448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint* feedback_data = (GLuint*)gl.mapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY); 776548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "MapBuffer"); 776648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 776748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::vec4<GLuint> routine_1_result; 776848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::vec4<GLuint> routine_2_result; 776948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 777048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos routine_1_result.m_x = feedback_data[0 + 0]; 777148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos routine_1_result.m_y = feedback_data[0 + 1]; 777248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos routine_1_result.m_z = feedback_data[0 + 2]; 777348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos routine_1_result.m_w = feedback_data[0 + 3]; 777448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 777548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos routine_2_result.m_x = feedback_data[4 + 0]; 777648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos routine_2_result.m_y = feedback_data[4 + 1]; 777748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos routine_2_result.m_z = feedback_data[4 + 2]; 777848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos routine_2_result.m_w = feedback_data[4 + 3]; 777948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 778048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Unmap buffer */ 778148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER); 778248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "UnmapBuffer"); 778348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 778448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Verifiy */ 778548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = result && 778648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos ((routine_1_result == expected_routine_1_result[0]) || (routine_1_result == expected_routine_1_result[1])); 778748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 778848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = result && 778948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos ((routine_2_result == expected_routine_2_result[0]) || (routine_2_result == expected_routine_2_result[1])); 779048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 779148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Log error if any */ 779248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (false == result) 779348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 779448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_context.getTestContext().getLog() << tcu::TestLog::Message << "Error. Invalid result." 779548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << tcu::TestLog::EndMessage; 779648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 779748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos tcu::MessageBuilder message = m_context.getTestContext().getLog() << tcu::TestLog::Message; 779848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 779948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos message << "Routine_1, result: "; 780048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 780148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos routine_1_result.log(message); 780248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 780348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos message << "Routine_2, result: "; 780448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 780548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos routine_2_result.log(message); 780648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 780748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos message << tcu::TestLog::EndMessage; 780848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 780948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 781048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Done */ 781148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return result; 781248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 781348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 781448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Execute draw call and verify results 781548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 781648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param routine_configuration Subroutine "type" ordinal 781748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param uni_input Input data 781848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param expected_routine_1_result Expected results of "routine_1" 781948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param expected_routine_2_result Expected results of "routine_2" 782048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 782148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return true if test pass, false otherwise 782248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 782348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosbool FunctionalTest14_15::testDraw(glw::GLuint routine_configuration, const Utils::vec4<glw::GLuint>& uni_input, 782448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const Utils::vec4<glw::GLuint>& expected_routine_1_result, 782548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const Utils::vec4<glw::GLuint>& expected_routine_2_result) const 782648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 782748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 782848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos bool result = true; 782948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint subroutine_indices[2]; 783048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLuint n_subroutine_uniforms = sizeof(subroutine_indices) / sizeof(subroutine_indices[0]); 783148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 783248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Set up input data uniforms */ 783348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.uniform4ui(m_uniform_location, uni_input.m_x, uni_input.m_y, uni_input.m_z, uni_input.m_w); 783448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "Uniform4f"); 783548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 783648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Prepare subroutine uniform data */ 783748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLuint i = 0; i < n_subroutine_uniforms; ++i) 783848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 783948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLuint location = m_subroutine_uniform_locations[i]; 784048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 784148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos subroutine_indices[location] = m_subroutine_indices[i][routine_configuration]; 784248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 784348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 784448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Set up subroutine uniforms */ 784548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.uniformSubroutinesuiv(GL_VERTEX_SHADER, n_subroutine_uniforms, &subroutine_indices[0]); 784648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "UniformSubroutinesuiv"); 784748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 784848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Execute draw call with transform feedback */ 784948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.beginTransformFeedback(GL_POINTS); 785048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback"); 785148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 785248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.drawArrays(GL_POINTS, 0 /* first */, 1 /* count */); 785348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays"); 785448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 785548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.endTransformFeedback(); 785648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback"); 785748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 785848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Capture results */ 785948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint* feedback_data = (GLuint*)gl.mapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY); 786048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "MapBuffer"); 786148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 786248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::vec4<GLuint> routine_1_result; 786348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::vec4<GLuint> routine_2_result; 786448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 786548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos routine_1_result.m_x = feedback_data[0 + 0]; 786648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos routine_1_result.m_y = feedback_data[0 + 1]; 786748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos routine_1_result.m_z = feedback_data[0 + 2]; 786848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos routine_1_result.m_w = feedback_data[0 + 3]; 786948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 787048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos routine_2_result.m_x = feedback_data[4 + 0]; 787148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos routine_2_result.m_y = feedback_data[4 + 1]; 787248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos routine_2_result.m_z = feedback_data[4 + 2]; 787348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos routine_2_result.m_w = feedback_data[4 + 3]; 787448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 787548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Unmap buffer */ 787648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER); 787748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "UnmapBuffer"); 787848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 787948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Verifiy */ 788048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = result && (routine_1_result == expected_routine_1_result); 788148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = result && (routine_2_result == expected_routine_2_result); 788248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 788348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Log error if any */ 788448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (false == result) 788548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 788648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_context.getTestContext().getLog() << tcu::TestLog::Message << "Error. Invalid result." 788748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << tcu::TestLog::EndMessage; 788848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 788948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos tcu::MessageBuilder message = m_context.getTestContext().getLog() << tcu::TestLog::Message; 789048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 789148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos message << "Routine_1, result: "; 789248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 789348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos routine_1_result.log(message); 789448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 789548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos message << ", expected: "; 789648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 789748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos expected_routine_1_result.log(message); 789848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 789948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos message << "Routine_2, result: "; 790048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 790148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos routine_2_result.log(message); 790248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 790348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos message << ", expected: "; 790448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 790548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos expected_routine_2_result.log(message); 790648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 790748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos message << tcu::TestLog::EndMessage; 790848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 790948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 791048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Done */ 791148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return result; 791248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 791348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 791448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Verify initial and current values of subroutine indices and subroutines uniform locations 791548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 791648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return true if test pass, false otherwise 791748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 791848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosbool FunctionalTest14_15::testIndicesAndLocations() const 791948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 792048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLuint n_subroutine_types = 2; 792148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos bool result = true; 792248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 792348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Verify subroutine indices */ 792448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLuint type = 0; type < n_subroutine_types; ++type) 792548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 792648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = result && (m_subroutine_indices[type][0] == m_initial_subroutine_indices[type][0]); 792748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = result && (m_subroutine_indices[type][1] == m_initial_subroutine_indices[type][1]); 792848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 792948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 793048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Verify subroutine uniform locations */ 793148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLuint uniform = 0; uniform < n_subroutine_types; ++uniform) 793248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 793348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = result && (m_subroutine_uniform_locations[uniform] == m_initial_subroutine_uniform_locations[uniform]); 793448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 793548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 793648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return result; 793748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 793848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 793948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Constructor. 794048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 794148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param context Rendering context. 794248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 794348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 794448087f5f0eb08759ee763f98daf3b34becb74559Pyry HaulosFunctionalTest16::FunctionalTest16(deqp::Context& context) 794548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos : TestCase(context, "subroutine_uniform_reset", 794648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "Checks that when the active program for a shader stage is re-linke or " 794748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "changed by a call to UseProgram, BindProgramPipeline, or UseProgramStages," 794848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " subroutine uniforms for that stage are reset to arbitrarily chosen default " 794948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "functions with compatible subroutine types.") 795048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_are_pipeline_objects_supported(false) 795148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_has_test_passed(true) 795248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 795348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos memset(m_fs_ids, 0, sizeof(m_fs_ids)); 795448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos memset(m_gs_ids, 0, sizeof(m_gs_ids)); 795548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos memset(m_po_ids, 0, sizeof(m_po_ids)); 795648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos memset(m_tc_ids, 0, sizeof(m_tc_ids)); 795748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos memset(m_te_ids, 0, sizeof(m_te_ids)); 795848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos memset(m_vs_ids, 0, sizeof(m_vs_ids)); 795948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 796048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos memset(m_fs_po_ids, 0, sizeof(m_fs_po_ids)); 796148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos memset(m_gs_po_ids, 0, sizeof(m_gs_po_ids)); 796248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos memset(m_pipeline_object_ids, 0, sizeof(m_pipeline_object_ids)); 796348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos memset(m_tc_po_ids, 0, sizeof(m_tc_po_ids)); 796448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos memset(m_te_po_ids, 0, sizeof(m_te_po_ids)); 796548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos memset(m_vs_po_ids, 0, sizeof(m_vs_po_ids)); 796648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 796748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 796848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Deinitializes all GL objects that may have been created during test execution. */ 796948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid FunctionalTest16::deinit() 797048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 797148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 797248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 797348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (unsigned int n_id = 0; n_id < 2; ++n_id) 797448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 797548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_fs_ids[n_id] != 0) 797648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 797748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteShader(m_fs_ids[n_id]); 797848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 797948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_fs_ids[n_id] = 0; 798048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 798148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 798248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_fs_po_ids[n_id] != 0) 798348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 798448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteProgram(m_fs_po_ids[n_id]); 798548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 798648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_fs_po_ids[n_id] = 0; 798748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 798848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 798948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_gs_ids[n_id] != 0) 799048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 799148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteShader(m_gs_ids[n_id]); 799248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 799348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_gs_ids[n_id] = 0; 799448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 799548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 799648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_gs_po_ids[n_id] != 0) 799748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 799848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteProgram(m_gs_po_ids[n_id]); 799948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 800048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_gs_po_ids[n_id] = 0; 800148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 800248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 800348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_pipeline_object_ids[n_id] != 0) 800448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 800548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteProgramPipelines(1 /* n */, m_pipeline_object_ids + n_id); 800648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 800748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 800848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_po_ids[n_id] != 0) 800948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 801048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteProgram(m_po_ids[n_id]); 801148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 801248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_po_ids[n_id] = 0; 801348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 801448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 801548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_tc_ids[n_id] != 0) 801648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 801748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteShader(m_tc_ids[n_id]); 801848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 801948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_tc_ids[n_id] = 0; 802048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 802148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 802248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_tc_po_ids[n_id] != 0) 802348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 802448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteProgram(m_tc_po_ids[n_id]); 802548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 802648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_tc_po_ids[n_id] = 0; 802748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 802848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 802948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_te_ids[n_id] != 0) 803048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 803148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteShader(m_te_ids[n_id]); 803248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 803348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_te_ids[n_id] = 0; 803448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 803548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 803648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_te_po_ids[n_id] != 0) 803748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 803848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteProgram(m_te_po_ids[n_id]); 803948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 804048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_te_po_ids[n_id] = 0; 804148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 804248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 804348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_vs_ids[n_id] != 0) 804448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 804548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteShader(m_vs_ids[n_id]); 804648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 804748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_vs_ids[n_id] = 0; 804848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 804948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 805048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_vs_po_ids[n_id] != 0) 805148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 805248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteProgram(m_vs_po_ids[n_id]); 805348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 805448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_vs_po_ids[n_id] = 0; 805548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 805648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } /* for (both IDs) */ 805748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 805848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 805948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Retrieves body of a shader that should be used for user-specified shader stage. 806048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * This function returns slightly different implementations, depending on index of 806148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * the program/pipeline object the shader will be used for. 806248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 806348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param shader_stage Stage the shader body is to be returned for. 806448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param n_id Index of the shader (as per description). 806548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 806648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return Requested string. 806748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 806848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosstd::string FunctionalTest16::getShaderBody(const Utils::_shader_stage& shader_stage, const unsigned int& n_id) const 806948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 807048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::stringstream result_sstream; 807148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 807248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "#version 400\n" 807348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 807448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "#extension GL_ARB_shader_subroutine : require\n" 807548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n"; 807648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 807748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos switch (shader_stage) 807848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 807948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case Utils::SHADER_STAGE_VERTEX: 808048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 808148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "out gl_PerVertex { vec4 gl_Position; } ;\n"; 808248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 808348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 808448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case Utils::SHADER_STAGE_GEOMETRY: 808548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 808648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "layout(points) in;\n" 808748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "layout(points, max_vertices = 1) out;\n"; 808848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "in gl_PerVertex { vec4 gl_Position; } gl_in[];\n"; 808948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "out gl_PerVertex { vec4 gl_Position; } ;\n"; 809048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 809148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 809248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 809348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case Utils::SHADER_STAGE_TESSELLATION_CONTROL: 809448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 809548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "layout(vertices = 4) out;\n"; 809648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "in gl_PerVertex { vec4 gl_Position; } gl_in[];\n"; 809748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "out gl_PerVertex { vec4 gl_Position; } gl_out[];\n"; 809848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 809948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 810048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 810148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case Utils::SHADER_STAGE_TESSELLATION_EVALUATION: 810248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 810348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "layout(quads) in;\n"; 810448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "in gl_PerVertex { vec4 gl_Position; } gl_in[];\n"; 810548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "out gl_PerVertex { vec4 gl_Position; };\n"; 810648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 810748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 810848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 810948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos default: 811048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 811148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } /* switch (shader_stage) */ 811248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 811348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "\n" 811448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine void subroutineType (inout vec4 result);\n" 811548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine vec4 subroutineType2(in vec4 data);\n" 811648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 811748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine(subroutineType) void function1(inout vec4 result)\n" 811848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 811948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " result += vec4(" 812048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << (n_id + 1) << ", " << (n_id + 2) << ", " << (n_id + 3) << ", " << (n_id + 4) 812148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << ");\n" 812248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 812348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine(subroutineType) void function2(inout vec4 result)\n" 812448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 812548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " result += vec4(" 812648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << (n_id + 2) << ", " << (n_id + 3) << ", " << (n_id + 4) << ", " << (n_id + 5) 812748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << ");\n" 812848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 812948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 813048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine(subroutineType2) vec4 function3(in vec4 data)\n" 813148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 813248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " return data * data;\n" 813348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 813448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine(subroutineType2) vec4 function4(in vec4 data)\n" 813548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 813648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " return data + data;\n" 813748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 813848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 813948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine uniform subroutineType subroutine1;\n" 814048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine uniform subroutineType subroutine2;\n" 814148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine uniform subroutineType2 subroutine3;\n" 814248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine uniform subroutineType2 subroutine4;\n" 814348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n"; 814448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 814548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (shader_stage == Utils::SHADER_STAGE_FRAGMENT) 814648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 814748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "out vec4 result;\n"; 814848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 814948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 815048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "void main()\n" 815148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n"; 815248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 815348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos switch (shader_stage) 815448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 815548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case Utils::SHADER_STAGE_FRAGMENT: 815648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 815748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << " result = vec4(0);\n" 815848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << " subroutine1(result);\n" 815948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " subroutine2(result);\n" 816048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " result = subroutine3(result) + subroutine4(result);\n"; 816148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 816248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 816348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 816448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 816548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case Utils::SHADER_STAGE_GEOMETRY: 816648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 816748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << " gl_Position = vec4(0);\n" 816848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " subroutine1(gl_Position);\n" 816948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " subroutine2(gl_Position);\n" 817048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " gl_Position = subroutine3(gl_Position) + subroutine4(gl_Position);\n" 817148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " EmitVertex();\n"; 817248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 817348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 817448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 817548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 817648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case Utils::SHADER_STAGE_TESSELLATION_CONTROL: 817748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 817848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << " gl_out[gl_InvocationID].gl_Position = vec4(0);\n" 817948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " subroutine1(gl_out[gl_InvocationID].gl_Position);\n" 818048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " subroutine2(gl_out[gl_InvocationID].gl_Position);\n" 818148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " gl_out[gl_InvocationID].gl_Position = subroutine3(gl_in[0].gl_Position) + " 818248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine4(gl_in[0].gl_Position);\n"; 818348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 818448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 818548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 818648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 818748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case Utils::SHADER_STAGE_VERTEX: 818848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case Utils::SHADER_STAGE_TESSELLATION_EVALUATION: 818948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 819048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << " gl_Position = vec4(0);\n" 819148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " subroutine1(gl_Position);\n" 819248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " subroutine2(gl_Position);\n" 819348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " gl_Position = subroutine3(gl_Position) + subroutine4(gl_Position);\n"; 819448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 819548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 819648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 819748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 819848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos default: 819948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 820048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } /* switch (shader_stage) */ 820148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 820248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "}\n"; 820348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 820448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return result_sstream.str(); 820548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 820648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 820748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Initializes all objects required to run the test. */ 820848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid FunctionalTest16::initTest() 820948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 821048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 821148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 821248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (unsigned int n_id = 0; n_id < 2 /* test program/shader objects */; ++n_id) 821348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 821448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const std::string fs_body = getShaderBody(Utils::SHADER_STAGE_FRAGMENT, n_id); 821548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const std::string gs_body = getShaderBody(Utils::SHADER_STAGE_GEOMETRY, n_id); 821648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const std::string tc_body = getShaderBody(Utils::SHADER_STAGE_TESSELLATION_CONTROL, n_id); 821748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const std::string te_body = getShaderBody(Utils::SHADER_STAGE_TESSELLATION_EVALUATION, n_id); 821848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const std::string vs_body = getShaderBody(Utils::SHADER_STAGE_VERTEX, n_id); 821948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 822048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!Utils::buildProgram(gl, vs_body, tc_body, te_body, gs_body, fs_body, DE_NULL, /* xfb_varyings */ 822148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos DE_NULL, /* n_xfb_varyings */ 822248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_vs_ids + n_id, m_tc_ids + n_id, m_te_ids + n_id, m_gs_ids + n_id, m_fs_ids + n_id, 822348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_po_ids + n_id)) 822448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 822548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.getLog() << tcu::TestLog::Message << "Failed to build test program object, index:" 822648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "[" 822748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << n_id << "]" << tcu::TestLog::EndMessage; 822848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 822948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos TCU_FAIL("Failed to build a test program"); 823048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 823148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 823248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_are_pipeline_objects_supported) 823348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 823448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Initialize shader program objects */ 823548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* fs_body_raw_ptr = fs_body.c_str(); 823648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* gs_body_raw_ptr = gs_body.c_str(); 823748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glw::GLint link_status[5] = { GL_FALSE }; 823848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* tc_body_raw_ptr = tc_body.c_str(); 823948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* te_body_raw_ptr = te_body.c_str(); 824048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* vs_body_raw_ptr = vs_body.c_str(); 824148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 824248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_fs_po_ids[n_id] = gl.createShaderProgramv(GL_FRAGMENT_SHADER, 1 /* count */, &fs_body_raw_ptr); 824348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_gs_po_ids[n_id] = gl.createShaderProgramv(GL_GEOMETRY_SHADER, 1 /* count */, &gs_body_raw_ptr); 824448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_tc_po_ids[n_id] = gl.createShaderProgramv(GL_TESS_CONTROL_SHADER, 1 /* count */, &tc_body_raw_ptr); 824548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_te_po_ids[n_id] = gl.createShaderProgramv(GL_TESS_EVALUATION_SHADER, 1 /* count */, &te_body_raw_ptr); 824648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_vs_po_ids[n_id] = gl.createShaderProgramv(GL_VERTEX_SHADER, 1 /* count */, &vs_body_raw_ptr); 824748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShaderProgramv() call failed."); 824848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 824948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getProgramiv(m_fs_po_ids[n_id], GL_LINK_STATUS, link_status + 0); 825048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getProgramiv(m_gs_po_ids[n_id], GL_LINK_STATUS, link_status + 1); 825148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getProgramiv(m_tc_po_ids[n_id], GL_LINK_STATUS, link_status + 2); 825248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getProgramiv(m_te_po_ids[n_id], GL_LINK_STATUS, link_status + 3); 825348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getProgramiv(m_vs_po_ids[n_id], GL_LINK_STATUS, link_status + 4); 825448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv() call failed."); 825548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 825648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (link_status[0] == GL_FALSE) 825748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos TCU_FAIL("Fragment shader program failed to link"); 825848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (link_status[1] == GL_FALSE) 825948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos TCU_FAIL("Geometry shader program failed to link"); 826048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (link_status[2] == GL_FALSE) 826148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos TCU_FAIL("Tessellation control shader program failed to link"); 826248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (link_status[3] == GL_FALSE) 826348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos TCU_FAIL("Tessellation evaluation shader program failed to link"); 826448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (link_status[4] == GL_FALSE) 826548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos TCU_FAIL("Vertex shader program failed to link"); 826648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 826748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Initialize pipeline program object */ 826848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.genProgramPipelines(1 /* n */, m_pipeline_object_ids + n_id); 826948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glGenProgramPipelines() call failed."); 827048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 827148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.useProgramStages(m_pipeline_object_ids[n_id], GL_FRAGMENT_SHADER_BIT, m_fs_po_ids[n_id]); 827248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.useProgramStages(m_pipeline_object_ids[n_id], GL_GEOMETRY_SHADER_BIT, m_gs_po_ids[n_id]); 827348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.useProgramStages(m_pipeline_object_ids[n_id], GL_TESS_CONTROL_SHADER_BIT, m_tc_po_ids[n_id]); 827448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.useProgramStages(m_pipeline_object_ids[n_id], GL_TESS_EVALUATION_SHADER_BIT, m_te_po_ids[n_id]); 827548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.useProgramStages(m_pipeline_object_ids[n_id], GL_VERTEX_SHADER_BIT, m_vs_po_ids[n_id]); 827648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgramStages() call failed."); 827748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 827848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 827948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Retrieve subroutine locations */ 828048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos struct _item 828148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 828248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glw::GLuint po_id; 828348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos _shader_stage& stage; 828448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glw::GLuint so_id; 828548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glw::GLenum so_type; 828648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } items[] = { 828748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { m_po_ids[n_id], m_po_descriptors[n_id].fragment, m_fs_ids[n_id], GL_FRAGMENT_SHADER }, 828848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { m_po_ids[n_id], m_po_descriptors[n_id].geometry, m_gs_ids[n_id], GL_GEOMETRY_SHADER }, 828948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { m_po_ids[n_id], m_po_descriptors[n_id].tess_control, m_tc_ids[n_id], GL_TESS_CONTROL_SHADER }, 829048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { m_po_ids[n_id], m_po_descriptors[n_id].tess_evaluation, m_te_ids[n_id], GL_TESS_EVALUATION_SHADER }, 829148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { m_po_ids[n_id], m_po_descriptors[n_id].vertex, m_vs_ids[n_id], GL_VERTEX_SHADER }, 829248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 829348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { m_fs_po_ids[n_id], m_fs_po_descriptors[n_id], m_fs_po_ids[n_id], GL_FRAGMENT_SHADER }, 829448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { m_gs_po_ids[n_id], m_gs_po_descriptors[n_id], m_gs_po_ids[n_id], GL_GEOMETRY_SHADER }, 829548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { m_tc_po_ids[n_id], m_tc_po_descriptors[n_id], m_tc_po_ids[n_id], GL_TESS_CONTROL_SHADER }, 829648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { m_te_po_ids[n_id], m_te_po_descriptors[n_id], m_te_po_ids[n_id], GL_TESS_EVALUATION_SHADER }, 829748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { m_vs_po_ids[n_id], m_vs_po_descriptors[n_id], m_vs_po_ids[n_id], GL_VERTEX_SHADER }, 829848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos }; 829948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const unsigned int n_items = sizeof(items) / sizeof(items[0]); 830048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 830148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (unsigned int n_item = 0; n_item < n_items; ++n_item) 830248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 830348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos _item& current_item = items[n_item]; 830448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 830548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos current_item.stage.function1_index = 830648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getSubroutineIndex(current_item.po_id, current_item.so_type, "function1"); 830748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos current_item.stage.function2_index = 830848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getSubroutineIndex(current_item.po_id, current_item.so_type, "function2"); 830948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos current_item.stage.function3_index = 831048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getSubroutineIndex(current_item.po_id, current_item.so_type, "function3"); 831148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos current_item.stage.function4_index = 831248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getSubroutineIndex(current_item.po_id, current_item.so_type, "function4"); 831348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glGetSubroutineIndex() call(s) failed."); 831448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 831548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (current_item.stage.function1_index == GL_INVALID_INDEX || 831648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos current_item.stage.function2_index == GL_INVALID_INDEX || 831748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos current_item.stage.function3_index == GL_INVALID_INDEX || 831848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos current_item.stage.function4_index == GL_INVALID_INDEX) 831948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 832048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos TCU_FAIL("Subroutine name was not recognized."); 832148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 832248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 832348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos current_item.stage.subroutine1_uniform_location = 832448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getSubroutineUniformLocation(current_item.po_id, current_item.so_type, "subroutine1"); 832548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos current_item.stage.subroutine2_uniform_location = 832648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getSubroutineUniformLocation(current_item.po_id, current_item.so_type, "subroutine2"); 832748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos current_item.stage.subroutine3_uniform_location = 832848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getSubroutineUniformLocation(current_item.po_id, current_item.so_type, "subroutine3"); 832948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos current_item.stage.subroutine4_uniform_location = 833048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getSubroutineUniformLocation(current_item.po_id, current_item.so_type, "subroutine4"); 833148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glGetSubroutineUniformLocation() call(s) failed."); 833248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 833348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (current_item.stage.subroutine1_uniform_location == -1 || 833448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos current_item.stage.subroutine2_uniform_location == -1 || 833548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos current_item.stage.subroutine3_uniform_location == -1 || 833648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos current_item.stage.subroutine4_uniform_location == -1) 833748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 833848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos TCU_FAIL("Subroutine uniform name was not recognized."); 833948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 834048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 834148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_po_ids[n_id] == current_item.po_id) 834248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 834348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.useProgram(current_item.po_id); 834448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed."); 834548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 834648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else 834748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 834848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Temporarily bind the program pipeline. */ 834948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.bindProgramPipeline(m_pipeline_object_ids[n_id]); 835048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glBindProgramPipeline() call failed."); 835148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 835248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 835348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getUniformSubroutineuiv(current_item.so_type, current_item.stage.subroutine1_uniform_location, 835448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos ¤t_item.stage.default_subroutine1_value); 835548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getUniformSubroutineuiv(current_item.so_type, current_item.stage.subroutine2_uniform_location, 835648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos ¤t_item.stage.default_subroutine2_value); 835748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getUniformSubroutineuiv(current_item.so_type, current_item.stage.subroutine3_uniform_location, 835848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos ¤t_item.stage.default_subroutine3_value); 835948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getUniformSubroutineuiv(current_item.so_type, current_item.stage.subroutine4_uniform_location, 836048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos ¤t_item.stage.default_subroutine4_value); 836148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformSubroutineuiv() call(s) failed."); 836248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 836348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos current_item.stage.gl_stage = current_item.so_type; 836448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 836548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_po_ids[n_id] != current_item.po_id) 836648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 836748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Unbind the program pipeline object */ 836848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.bindProgramPipeline(0); 836948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glBindProgramPipeline() call failed."); 837048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 837148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } /* for (all items) */ 837248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 837348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Make sure the default subroutine choices are valid. */ 837448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos verifySubroutineUniformValues( 837548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos TEST_CASE_SWITCH_TO_DIFFERENT_PROGRAM_OBJECT, /* makes the verification routine use program object descriptor */ 837648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos n_id, SUBROUTINE_UNIFORMS_SET_TO_VALID_VALUES); 837748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 837848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_are_pipeline_objects_supported) 837948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 838048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.useProgram(0); 838148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed."); 838248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 838348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.bindProgramPipeline(m_pipeline_object_ids[n_id]); 838448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glBindProgramPipeline() call failed."); 838548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 838648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos verifySubroutineUniformValues( 838748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos TEST_CASE_SWITCH_TO_DIFFERENT_PROGRAM_PIPELINE_OBJECT, /* makes the verification routine use pipeline object descriptor */ 838848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos n_id, SUBROUTINE_UNIFORMS_SET_TO_VALID_VALUES); 838948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 839048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.bindProgramPipeline(0); 839148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glBindProgramPipeline() call failed."); 839248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 839348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } /* for (both program descriptors) */ 839448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 839548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 839648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Retrieves IDs of shaders OR shader program objects, depending on which of the two 839748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * the caller requests for. 839848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 839948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param retrieve_program_object_shader_ids true if the caller wishes to retrieve shader object IDs, 840048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * false to return shader program IDs. 840148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param n_id Index of the program/pipeline object the shaders 840248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * are a part of. 840348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param out_shader_stages Deref will be used to store exactly five IDs. Must not 840448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * be NULL. 840548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 840648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid FunctionalTest16::getShaderStages(bool retrieve_program_object_shader_ids, const unsigned int& n_id, 840748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const _shader_stage** out_shader_stages) const 840848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 840948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (retrieve_program_object_shader_ids) 841048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 841148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos out_shader_stages[0] = &m_po_descriptors[n_id].vertex; 841248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos out_shader_stages[1] = &m_po_descriptors[n_id].tess_control; 841348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos out_shader_stages[2] = &m_po_descriptors[n_id].tess_evaluation; 841448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos out_shader_stages[3] = &m_po_descriptors[n_id].geometry; 841548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos out_shader_stages[4] = &m_po_descriptors[n_id].fragment; 841648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 841748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else 841848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 841948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos out_shader_stages[0] = m_vs_po_descriptors + n_id; 842048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos out_shader_stages[1] = m_tc_po_descriptors + n_id; 842148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos out_shader_stages[2] = m_te_po_descriptors + n_id; 842248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos out_shader_stages[3] = m_gs_po_descriptors + n_id; 842348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos out_shader_stages[4] = m_fs_po_descriptors + n_id; 842448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 842548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 842648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 842748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Executes test iteration. 842848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 842948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed. 843048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos */ 843148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulostcu::TestNode::IterateResult FunctionalTest16::iterate() 843248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 843348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 843448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 843548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Do not execute the test if GL_ARB_shader_subroutine is not supported */ 843648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_shader_subroutine")) 843748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 843848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos throw tcu::NotSupportedError("GL_ARB_shader_subroutine is not supported."); 843948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 844048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 844148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_are_pipeline_objects_supported = 844248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_context.getContextInfo().isExtensionSupported("GL_ARB_separate_shader_objects"); 844348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 844448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Initialize GL objects required to run the test */ 844548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos initTest(); 844648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 844748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Iterate over both pipelines/programs and verify that calling glUseProgram() / 844848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * glBindProgramPipeline() / glUseProgramStages() resets subroutine uniform configuration. 844948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos */ 845048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (int test_case = static_cast<int>(TEST_CASE_FIRST); test_case != static_cast<int>(TEST_CASE_COUNT); ++test_case) 845148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 845248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (static_cast<_test_case>(test_case) != TEST_CASE_SWITCH_TO_DIFFERENT_PROGRAM_OBJECT && 845348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos !m_are_pipeline_objects_supported) 845448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 845548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Current test case requires GL_ARB_separate_shader_objects support which is 845648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * unavaiable on the platform that we're testing 845748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos */ 845848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos continue; 845948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 846048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 846148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (unsigned int n_object_id = 0; n_object_id < 2; /* pipeline/program objects allocated for the test */ 846248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos ++n_object_id) 846348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 846448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Verify that currently reported subroutine uniform values are equal to default values */ 846548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (test_case == TEST_CASE_SWITCH_TO_DIFFERENT_PROGRAM_OBJECT) 846648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 846748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.useProgram(m_po_ids[n_object_id]); 846848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed"); 846948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 847048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else 847148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 847248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.bindProgramPipeline(m_pipeline_object_ids[n_object_id]); 847348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glBindProgramPipeline() call failed"); 847448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 847548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 847648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos verifySubroutineUniformValues(static_cast<_test_case>(test_case), n_object_id, 847748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos SUBROUTINE_UNIFORMS_SET_TO_DEFAULT_VALUES); 847848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 847948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Re-configure subroutine uniforms so that they point to different subroutines than 848048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * the default ones. 848148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos */ 848248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const _shader_stage* stages[5 /* fs+gs+tc+te+vs */] = { DE_NULL }; 848348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 848448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos getShaderStages(static_cast<_test_case>(test_case) == TEST_CASE_SWITCH_TO_DIFFERENT_PROGRAM_OBJECT, 848548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos n_object_id, stages); 848648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 848748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (unsigned int n_stage = 0; n_stage < 5 /* fs+gs+tc+te+vs stages */; ++n_stage) 848848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 848948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const _shader_stage& current_stage = *(stages[n_stage]); 849048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glw::GLuint subroutine_configuration[4] = { GL_INVALID_INDEX }; 849148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 849248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos subroutine_configuration[0] = 849348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos (current_stage.default_subroutine1_value == current_stage.function1_index) ? 849448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos current_stage.function2_index : 849548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos current_stage.function1_index; 849648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos subroutine_configuration[1] = 849748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos (current_stage.default_subroutine2_value == current_stage.function1_index) ? 849848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos current_stage.function2_index : 849948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos current_stage.function1_index; 850048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos subroutine_configuration[2] = 850148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos (current_stage.default_subroutine3_value == current_stage.function3_index) ? 850248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos current_stage.function4_index : 850348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos current_stage.function3_index; 850448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos subroutine_configuration[3] = 850548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos (current_stage.default_subroutine4_value == current_stage.function3_index) ? 850648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos current_stage.function4_index : 850748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos current_stage.function3_index; 850848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 850948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.uniformSubroutinesuiv(current_stage.gl_stage, 4 /* count */, subroutine_configuration); 851048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glUniformSubroutinesuiv() call failed."); 851148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } /* for (all stages) */ 851248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 851348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos verifySubroutineUniformValues(static_cast<_test_case>(test_case), n_object_id, 851448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos SUBROUTINE_UNIFORMS_SET_TO_NONDEFAULT_VALUES); 851548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 851648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Execute test case-specific code */ 851748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos _shader_stage cached_shader_stage_data; 851848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos bool stage_reset_status[Utils::SHADER_STAGE_COUNT] = { false, false, false, false, false }; 851948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos bool uses_stage_reset_status = false; 852048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 852148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos switch (test_case) 852248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 852348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case TEST_CASE_SWITCH_TO_DIFFERENT_PROGRAM_OBJECT: 852448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 852548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Switch to a different program object and then back to current PO. 852648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * Subroutine uniforms should be back at their default settings, instead of 852748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * the ones we've just set. 852848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos */ 852948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.useProgram(m_po_ids[(n_object_id + 1) % 2 /* objects allocated for the test */]); 853048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.useProgram(m_po_ids[n_object_id]); 853148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call(s) failed."); 853248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 853348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 853448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 853548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 853648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case TEST_CASE_SWITCH_TO_DIFFERENT_PROGRAM_PIPELINE_OBJECT: 853748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 853848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Switch to a different pipeline object and then back to the current one. 853948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * Subroutine uniforms should be back at their default settings, instead of 854048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * the ones we've just set. 854148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos */ 854248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.bindProgramPipeline( 854348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_pipeline_object_ids[(n_object_id + 1) % 2 /* objects allocated for the test */]); 854448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.bindProgramPipeline(m_pipeline_object_ids[n_object_id]); 854548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glBindProgramPipeline() call(s) failed."); 854648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 854748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 854848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 854948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 855048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case TEST_CASE_SWITCH_TO_DIFFERENT_PIPELINE_FRAGMENT_STAGE: 855148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 855248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Change the fragment shader stage to a different one. 855348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 855448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * Note: We also need to update internal descriptor since the subroutine/uniform 855548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * locations may be different between the two programs. 855648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos */ 855748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.useProgramStages(m_pipeline_object_ids[n_object_id], GL_FRAGMENT_SHADER_BIT, 855848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_fs_po_ids[(n_object_id + 1) % 2 /* objects allocated for the test */]); 855948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgramStages() call failed."); 856048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 856148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos cached_shader_stage_data = m_fs_po_descriptors[n_object_id]; 856248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_fs_po_descriptors[n_object_id] = m_fs_po_descriptors[(n_object_id + 1) % 2]; 856348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 856448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos stage_reset_status[Utils::SHADER_STAGE_FRAGMENT] = true; 856548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos uses_stage_reset_status = true; 856648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 856748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 856848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 856948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 857048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case TEST_CASE_SWITCH_TO_DIFFERENT_PIPELINE_GEOMETRY_STAGE: 857148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 857248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Change the geometry shader stage to a different one. 857348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 857448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * Note: We also need to update internal descriptor since the subroutine/uniform 857548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * locations may be different between the two programs. 857648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos */ 857748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.useProgramStages(m_pipeline_object_ids[n_object_id], GL_GEOMETRY_SHADER_BIT, 857848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_gs_po_ids[(n_object_id + 1) % 2 /* objects allocated for the test */]); 857948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgramStages() call failed."); 858048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 858148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos cached_shader_stage_data = m_gs_po_descriptors[n_object_id]; 858248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_gs_po_descriptors[n_object_id] = m_gs_po_descriptors[(n_object_id + 1) % 2]; 858348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 858448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos stage_reset_status[Utils::SHADER_STAGE_GEOMETRY] = true; 858548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos uses_stage_reset_status = true; 858648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 858748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 858848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 858948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 859048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case TEST_CASE_SWITCH_TO_DIFFERENT_PIPELINE_TESS_CONTROL_STAGE: 859148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 859248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Change the tessellation control shader stage to a different one. 859348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 859448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * Note: We also need to update internal descriptor since the subroutine/uniform 859548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * locations may be different between the two programs. 859648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos */ 859748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.useProgramStages(m_pipeline_object_ids[n_object_id], GL_TESS_CONTROL_SHADER_BIT, 859848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_tc_po_ids[(n_object_id + 1) % 2 /* objects allocated for the test */]); 859948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgramStages() call failed."); 860048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 860148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos cached_shader_stage_data = m_tc_po_descriptors[n_object_id]; 860248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_tc_po_descriptors[n_object_id] = m_tc_po_descriptors[(n_object_id + 1) % 2]; 860348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 860448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos stage_reset_status[Utils::SHADER_STAGE_TESSELLATION_CONTROL] = true; 860548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos uses_stage_reset_status = true; 860648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 860748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 860848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 860948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 861048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case TEST_CASE_SWITCH_TO_DIFFERENT_PIPELINE_TESS_EVALUATION_STAGE: 861148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 861248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Change the tessellation evaluation shader stage to a different one. 861348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 861448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * Note: We also need to update internal descriptor since the subroutine/uniform 861548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * locations may be different between the two programs. 861648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos */ 861748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.useProgramStages(m_pipeline_object_ids[n_object_id], GL_TESS_EVALUATION_SHADER_BIT, 861848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_te_po_ids[(n_object_id + 1) % 2 /* objects allocated for the test */]); 861948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgramStages() call failed."); 862048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 862148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos cached_shader_stage_data = m_te_po_descriptors[n_object_id]; 862248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_te_po_descriptors[n_object_id] = m_te_po_descriptors[(n_object_id + 1) % 2]; 862348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 862448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos stage_reset_status[Utils::SHADER_STAGE_TESSELLATION_EVALUATION] = true; 862548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos uses_stage_reset_status = true; 862648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 862748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 862848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 862948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 863048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case TEST_CASE_SWITCH_TO_DIFFERENT_PIPELINE_VERTEX_STAGE: 863148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 863248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Change the vertex shader stage to a different one. 863348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 863448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * Note: We also need to update internal descriptor since the subroutine/uniform 863548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * locations may be different between the two programs. 863648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos */ 863748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.useProgramStages(m_pipeline_object_ids[n_object_id], GL_VERTEX_SHADER_BIT, 863848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_vs_po_ids[(n_object_id + 1) % 2 /* objects allocated for the test */]); 863948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgramStages() call failed."); 864048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 864148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos cached_shader_stage_data = m_vs_po_descriptors[n_object_id]; 864248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_vs_po_descriptors[n_object_id] = m_vs_po_descriptors[(n_object_id + 1) % 2]; 864348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 864448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos stage_reset_status[Utils::SHADER_STAGE_VERTEX] = true; 864548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos uses_stage_reset_status = true; 864648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 864748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 864848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 864948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 865048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos default: 865148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 865248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos TCU_FAIL("Unrecognized test case"); 865348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 865448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } /* switch (test_case) */ 865548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 865648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Verify the subroutine uniform values are valid */ 865748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!uses_stage_reset_status) 865848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 865948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos verifySubroutineUniformValues(static_cast<_test_case>(test_case), n_object_id, 866048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos SUBROUTINE_UNIFORMS_SET_TO_DEFAULT_VALUES); 866148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 866248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else 866348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 866448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const _shader_stage* shader_stages[Utils::SHADER_STAGE_COUNT] = { DE_NULL }; 866548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 866648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos getShaderStages(static_cast<_test_case>(test_case) == TEST_CASE_SWITCH_TO_DIFFERENT_PROGRAM_OBJECT, 866748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos n_object_id, shader_stages); 866848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 866948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (unsigned int n_shader_stage = 0; n_shader_stage < Utils::SHADER_STAGE_COUNT; ++n_shader_stage) 867048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 867148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const _shader_stage& current_shader_stage = *(shader_stages[n_shader_stage]); 867248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 867348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (stage_reset_status[n_shader_stage]) 867448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 867548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos verifySubroutineUniformValuesForShaderStage(current_shader_stage, 867648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos SUBROUTINE_UNIFORMS_SET_TO_DEFAULT_VALUES); 867748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 867848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else 867948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 868048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos verifySubroutineUniformValuesForShaderStage(current_shader_stage, 868148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos SUBROUTINE_UNIFORMS_SET_TO_NONDEFAULT_VALUES); 868248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 868348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } /* for (all shader stages) */ 868448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 868548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 868648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Revert the changes some of the test cases appied */ 868748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos switch (test_case) 868848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 868948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case TEST_CASE_SWITCH_TO_DIFFERENT_PIPELINE_FRAGMENT_STAGE: 869048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 869148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.useProgramStages(m_pipeline_object_ids[n_object_id], GL_FRAGMENT_SHADER_BIT, 869248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_fs_po_ids[n_object_id]); 869348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgramStages() call failed."); 869448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 869548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_fs_po_descriptors[n_object_id] = cached_shader_stage_data; 869648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 869748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 869848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 869948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 870048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case TEST_CASE_SWITCH_TO_DIFFERENT_PIPELINE_GEOMETRY_STAGE: 870148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 870248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.useProgramStages(m_pipeline_object_ids[n_object_id], GL_GEOMETRY_SHADER_BIT, 870348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_gs_po_ids[n_object_id]); 870448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgramStages() call failed."); 870548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 870648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_gs_po_descriptors[n_object_id] = cached_shader_stage_data; 870748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 870848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 870948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 871048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 871148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case TEST_CASE_SWITCH_TO_DIFFERENT_PIPELINE_TESS_CONTROL_STAGE: 871248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 871348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.useProgramStages(m_pipeline_object_ids[n_object_id], GL_TESS_CONTROL_SHADER_BIT, 871448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_tc_po_ids[n_object_id]); 871548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgramStages() call failed."); 871648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 871748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_tc_po_descriptors[n_object_id] = cached_shader_stage_data; 871848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 871948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 872048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 872148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 872248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case TEST_CASE_SWITCH_TO_DIFFERENT_PIPELINE_TESS_EVALUATION_STAGE: 872348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 872448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.useProgramStages(m_pipeline_object_ids[n_object_id], GL_TESS_EVALUATION_SHADER_BIT, 872548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_te_po_ids[n_object_id]); 872648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgramStages() call failed."); 872748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 872848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_te_po_descriptors[n_object_id] = cached_shader_stage_data; 872948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 873048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 873148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 873248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 873348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case TEST_CASE_SWITCH_TO_DIFFERENT_PIPELINE_VERTEX_STAGE: 873448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 873548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.useProgramStages(m_pipeline_object_ids[n_object_id], GL_VERTEX_SHADER_BIT, m_vs_po_ids[n_object_id]); 873648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgramStages() call failed."); 873748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 873848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_vs_po_descriptors[n_object_id] = cached_shader_stage_data; 873948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 874048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 874148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 874248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 874348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos default: 874448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 874548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } /* switch (test_case) */ 874648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 874748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } /* for (all program object descriptors) */ 874848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 874948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Unbind the program object */ 875048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.useProgram(0); 875148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed."); 875248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } /* for (all test cases) */ 875348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 875448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_has_test_passed) 875548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 875648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 875748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 875848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else 875948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 876048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 876148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 876248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 876348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return STOP; 876448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 876548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 876648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Verifies the subroutine uniform values reported by GL implementation. Depending on the test case, 876748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * it will either query program object stages or separate shader objects. 876848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 876948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param test_case Test case the verification is to be performed for. 877048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param n_id Index of the program/pipeline object to use for the verification 877148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param verification Verification method. 877248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos */ 877348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid FunctionalTest16::verifySubroutineUniformValues(const _test_case& test_case, const unsigned int& n_id, 877448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const _subroutine_uniform_value_verification& verification) 877548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 877648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const _shader_stage* stages[] = { 877748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos DE_NULL, /* fragment shader stage slot */ 877848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos DE_NULL, /* geometry shader stage slot */ 877948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos DE_NULL, /* tess control shader stage slot */ 878048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos DE_NULL, /* tess eval shader stage slot */ 878148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos DE_NULL /* vertex shader stage slot */ 878248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos }; 878348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const unsigned int n_stages = sizeof(stages) / sizeof(stages[0]); 878448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 878548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Verify that currently reported subroutine uniform values are equal to default values */ 878648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos getShaderStages(test_case == TEST_CASE_SWITCH_TO_DIFFERENT_PROGRAM_OBJECT, n_id, stages); 878748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 878848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (unsigned int n_stage = 0; n_stage < n_stages; ++n_stage) 878948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 879048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const _shader_stage& current_stage = *(stages[n_stage]); 879148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 879248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos verifySubroutineUniformValuesForShaderStage(current_stage, verification); 879348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } /* for (all items) */ 879448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 879548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 879648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Verifies the subroutine uniform values reported by GL implementation for user-specified 879748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * shader stage. If the verification fails, m_has_test_passed will be set to false. 879848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 879948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param shader_stage Descriptor of a shader stage that should be used for the process. 880048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param verification Type of verification that should be performed. 880148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 880248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 880348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid FunctionalTest16::verifySubroutineUniformValuesForShaderStage( 880448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const _shader_stage& shader_stage, const _subroutine_uniform_value_verification& verification) 880548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 880648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 880748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glw::GLuint result_values[4] = { 0 }; 880848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 880948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getUniformSubroutineuiv(shader_stage.gl_stage, shader_stage.subroutine1_uniform_location, result_values + 0); 881048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getUniformSubroutineuiv(shader_stage.gl_stage, shader_stage.subroutine2_uniform_location, result_values + 1); 881148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getUniformSubroutineuiv(shader_stage.gl_stage, shader_stage.subroutine3_uniform_location, result_values + 2); 881248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getUniformSubroutineuiv(shader_stage.gl_stage, shader_stage.subroutine4_uniform_location, result_values + 3); 881348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformSubroutineuiv() call(s) failed."); 881448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 881548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (verification == SUBROUTINE_UNIFORMS_SET_TO_VALID_VALUES) 881648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 881748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!((result_values[0] == (GLuint)shader_stage.subroutine1_uniform_location || 881848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_values[0] == (GLuint)shader_stage.subroutine2_uniform_location) && 881948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos (result_values[1] == (GLuint)shader_stage.subroutine1_uniform_location || 882048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_values[1] == (GLuint)shader_stage.subroutine2_uniform_location) && 882148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos (result_values[2] == (GLuint)shader_stage.subroutine3_uniform_location || 882248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_values[2] == (GLuint)shader_stage.subroutine4_uniform_location) && 882348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos (result_values[3] == (GLuint)shader_stage.subroutine3_uniform_location || 882448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_values[3] == (GLuint)shader_stage.subroutine4_uniform_location))) 882548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 882648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.getLog() << tcu::TestLog::Message << "SUBROUTINE_UNIFORMS_SET_TO_VALID_VALUES validation failed. " 882748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "Shader stage:[" 882848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << Utils::getShaderStageStringFromGLEnum(shader_stage.gl_stage) << "], " 882948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "expected data:[" 883048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << shader_stage.subroutine1_uniform_location << " OR " 883148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << shader_stage.subroutine2_uniform_location << " x 2, " 883248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << shader_stage.subroutine3_uniform_location << " OR " 883348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << shader_stage.subroutine4_uniform_location << " x 2], " 883448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "found data:[" 883548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << result_values[0] << ", " << result_values[1] << ", " << result_values[2] << ", " 883648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << result_values[3] << "]." << tcu::TestLog::EndMessage; 883748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 883848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_has_test_passed = false; 883948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 884048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 884148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else if (verification == SUBROUTINE_UNIFORMS_SET_TO_DEFAULT_VALUES) 884248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 884348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (result_values[0] != shader_stage.default_subroutine1_value || 884448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_values[1] != shader_stage.default_subroutine2_value || 884548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_values[2] != shader_stage.default_subroutine3_value || 884648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_values[3] != shader_stage.default_subroutine4_value) 884748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 884848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.getLog() << tcu::TestLog::Message 884948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << "SUBROUTINE_UNIFORMS_SET_TO_DEFAULT_VALUES validation failed. " 885048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "Shader stage:[" 885148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << Utils::getShaderStageStringFromGLEnum(shader_stage.gl_stage) << "], " 885248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "expected data:[" 885348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << shader_stage.default_subroutine1_value << ", " 885448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << shader_stage.default_subroutine2_value << ", " 885548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << shader_stage.default_subroutine3_value << ", " 885648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << shader_stage.default_subroutine4_value << "], " 885748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "found data:[" 885848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << result_values[0] << ", " << result_values[1] << ", " << result_values[2] << ", " 885948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << result_values[3] << "]." << tcu::TestLog::EndMessage; 886048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 886148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_has_test_passed = false; 886248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 886348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 886448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else 886548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 886648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos DE_ASSERT(verification == SUBROUTINE_UNIFORMS_SET_TO_NONDEFAULT_VALUES); 886748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 886848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (result_values[0] == shader_stage.default_subroutine1_value || 886948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_values[1] == shader_stage.default_subroutine2_value || 887048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_values[2] == shader_stage.default_subroutine3_value || 887148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_values[3] == shader_stage.default_subroutine4_value) 887248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 887348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.getLog() << tcu::TestLog::Message 887448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << "SUBROUTINE_UNIFORMS_SET_TO_NONDEFAULT_VALUES validation failed. " 887548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "Shader stage:[" 887648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << Utils::getShaderStageStringFromGLEnum(shader_stage.gl_stage) << "], " 887748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "expected data:![" 887848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << shader_stage.default_subroutine1_value << ", " 887948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << shader_stage.default_subroutine2_value << ", " 888048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << shader_stage.default_subroutine3_value << ", " 888148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << shader_stage.default_subroutine4_value << "], " 888248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "found data:[" 888348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << result_values[0] << ", " << result_values[1] << ", " << result_values[2] << ", " 888448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << result_values[3] << "]." << tcu::TestLog::EndMessage; 888548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 888648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_has_test_passed = false; 888748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 888848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 888948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 889048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 889148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Constructor. 889248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 889348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param context Rendering context. 889448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 889548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 889648087f5f0eb08759ee763f98daf3b34becb74559Pyry HaulosFunctionalTest17::FunctionalTest17(deqp::Context& context) 889748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos : TestCase(context, "same_subroutine_and_subroutine_uniform_but_different_type_used_in_all_stages", 889848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "Creates a program which uses the same subroutine and subroutine uniform " 889948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "names for every stage (types of subroutines are different in each stage) " 890048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "and then makes sure that such program compiles and works as expected.") 890148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_fbo_id(0) 890248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_fs_id(0) 890348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_gs_id(0) 890448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_has_test_passed(true) 890548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_po_id(0) 890648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_tc_id(0) 890748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_te_id(0) 890848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_to_data(DE_NULL) 890948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_to_height(4) /* arbitrary value */ 891048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_to_id(0) 891148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_to_width(4) /* arbitrary value */ 891248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_vao_id(0) 891348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_vs_id(0) 891448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 891548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Left blank intentionally */ 891648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 891748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 891848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Deinitializes all GL objects that may have been created during test execution. */ 891948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid FunctionalTest17::deinit() 892048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 892148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 892248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 892348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_fbo_id != 0) 892448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 892548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteFramebuffers(1, &m_fbo_id); 892648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 892748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_fbo_id = 0; 892848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 892948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 893048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_fs_id != 0) 893148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 893248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteShader(m_fs_id); 893348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 893448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_fs_id = 0; 893548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 893648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 893748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_gs_id != 0) 893848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 893948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteShader(m_gs_id); 894048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 894148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_gs_id = 0; 894248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 894348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 894448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_po_id != 0) 894548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 894648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteProgram(m_po_id); 894748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 894848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_po_id = 0; 894948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 895048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 895148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_tc_id != 0) 895248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 895348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteShader(m_tc_id); 895448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 895548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_tc_id = 0; 895648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 895748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 895848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_te_id != 0) 895948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 896048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteShader(m_te_id); 896148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 896248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_te_id = 0; 896348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 896448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 896548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_to_data != DE_NULL) 896648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 896748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos delete[] m_to_data; 896848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 896948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_to_data = DE_NULL; 897048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 897148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 897248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_to_id != 0) 897348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 897448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteTextures(1, &m_to_id); 897548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 897648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_to_id = 0; 897748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 897848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 897948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_vao_id != 0) 898048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 898148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteVertexArrays(1, &m_vao_id); 898248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 898348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_vao_id = 0; 898448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 898548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 898648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_vs_id != 0) 898748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 898848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteShader(m_vs_id); 898948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 899048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_vs_id = 0; 899148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 899248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 899348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Restore original GL configuration */ 899448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.patchParameteri(GL_PATCH_VERTICES, 3); 899548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glPatchParameteri() call failed."); 899648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 899748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.pixelStorei(GL_PACK_ALIGNMENT, 4); 899848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glPixelStorei() call failed."); 899948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 900048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 900148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Retrieves body of a fragment shader that should be used by the test program. 900248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 900348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return Requested string. 900448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 900548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosstd::string FunctionalTest17::getFragmentShaderBody() const 900648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 900748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return "#version 400\n" 900848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 900948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "#extension GL_ARB_shader_subroutine : require\n" 901048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 901148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "in GS_DATA\n" 901248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 901348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " vec4 gs_data;\n" 901448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " vec4 tc_data;\n" 901548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " vec4 te_data;\n" 901648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " vec4 vs_data;\n" 901748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "} gs;\n" 901848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 901948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "out vec4 result;\n" 902048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 902148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine void subroutineTypeFS(out vec4 result);\n" 902248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 902348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine(subroutineTypeFS) void subroutine1(out vec4 result)\n" 902448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 902548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " result = vec4(5, 6, 7, 8);\n" 902648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 902748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 902848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine uniform subroutineTypeFS function;\n" 902948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 903048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void main()\n" 903148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 903248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " vec4 fs_data;\n" 903348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 903448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " function(fs_data);\n" 903548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " result = gs.gs_data + gs.tc_data + gs.te_data + gs.vs_data + fs_data;\n" 903648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n"; 903748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 903848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 903948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Retrieves body of a geometry shader that should be used by the test program. 904048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 904148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return Requested string. 904248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 904348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosstd::string FunctionalTest17::getGeometryShaderBody() const 904448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 904548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return "#version 400\n" 904648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 904748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "#extension GL_ARB_shader_subroutine : require\n" 904848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 904948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "layout(points) in;\n" 905048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "layout(triangle_strip, max_vertices = 4) out;\n" 905148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 905248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine void subroutineTypeGS(out vec4 result);\n" 905348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 905448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine(subroutineTypeGS) void subroutine1(out vec4 result)\n" 905548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 905648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " result = vec4(4, 5, 6, 7);\n" 905748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 905848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 905948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine uniform subroutineTypeGS function;\n" 906048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 906148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "in TE_DATA\n" 906248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 906348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " vec4 tc_data;\n" 906448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " vec4 te_data;\n" 906548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " vec4 vs_data;\n" 906648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "} te[];\n" 906748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 906848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "out GS_DATA\n" 906948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 907048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " vec4 gs_data;\n" 907148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " vec4 tc_data;\n" 907248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " vec4 te_data;\n" 907348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " vec4 vs_data;\n" 907448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "} result;\n" 907548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 907648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void main()\n" 907748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 907848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " function(result.gs_data);\n" 907948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " gl_Position = vec4(1, -1, 0, 1);\n" 908048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " result.tc_data = te[0].tc_data;\n" 908148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " result.te_data = te[0].te_data;\n" 908248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " result.vs_data = te[0].vs_data;\n" 908348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " EmitVertex();\n" 908448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 908548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " function(result.gs_data);\n" 908648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " gl_Position = vec4(-1, -1, 0, 1);\n" 908748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " result.tc_data = te[0].tc_data;\n" 908848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " result.te_data = te[0].te_data;\n" 908948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " result.vs_data = te[0].vs_data;\n" 909048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " EmitVertex();\n" 909148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 909248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " function(result.gs_data);\n" 909348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " gl_Position = vec4(1, 1, 0, 1);\n" 909448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " result.tc_data = te[0].tc_data;\n" 909548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " result.te_data = te[0].te_data;\n" 909648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " result.vs_data = te[0].vs_data;\n" 909748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " EmitVertex();\n" 909848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 909948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " function(result.gs_data);\n" 910048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " gl_Position = vec4(-1, 1, 0, 1);\n" 910148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " result.tc_data = te[0].tc_data;\n" 910248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " result.te_data = te[0].te_data;\n" 910348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " result.vs_data = te[0].vs_data;\n" 910448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " EmitVertex();\n" 910548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " EndPrimitive();\n" 910648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n"; 910748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 910848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 910948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Retrieves body of a tessellation control shader that should be used by the test program. 911048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 911148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return Requested string. 911248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 911348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosstd::string FunctionalTest17::getTessellationControlShaderBody() const 911448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 911548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return "#version 400\n" 911648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 911748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "#extension GL_ARB_shader_subroutine : require\n" 911848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 911948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "layout (vertices = 4) out;\n" 912048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 912148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine void subroutineTypeTC(out vec4 result);\n" 912248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 912348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine(subroutineTypeTC) void subroutine1(out vec4 result)\n" 912448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 912548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " result = vec4(2, 3, 4, 5);\n" 912648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 912748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 912848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine uniform subroutineTypeTC function;\n" 912948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 913048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "in VS_DATA\n" 913148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 913248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " vec4 vs_data;\n" 913348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "} vs[];\n" 913448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 913548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "out TC_DATA\n" 913648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 913748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " vec4 tc_data;\n" 913848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " vec4 vs_data;\n" 913948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "} result[];\n" 914048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 914148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void main()\n" 914248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 914348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " gl_TessLevelInner[0] = 1.0;\n" 914448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " gl_TessLevelInner[1] = 1.0;\n" 914548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " gl_TessLevelOuter[0] = 1.0;\n" 914648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " gl_TessLevelOuter[1] = 1.0;\n" 914748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " gl_TessLevelOuter[2] = 1.0;\n" 914848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " gl_TessLevelOuter[3] = 1.0;\n" 914948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 915048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " function(result[gl_InvocationID].tc_data);\n" 915148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " result[gl_InvocationID].vs_data = vs[gl_InvocationID].vs_data;\n" 915248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n"; 915348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 915448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 915548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Retrieves body of a tessellation evaluation shader that should be used 915648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * by the test program. 915748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 915848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return Requested string. 915948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 916048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosstd::string FunctionalTest17::getTessellationEvaluationShaderBody() const 916148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 916248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return "#version 400\n" 916348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 916448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "#extension GL_ARB_shader_subroutine : require\n" 916548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 916648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "layout (quads, point_mode) in;\n" 916748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 916848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine void subroutineTypeTE(out vec4 result);\n" 916948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 917048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine(subroutineTypeTE) void subroutine1(out vec4 result)\n" 917148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 917248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " result = vec4(3, 4, 5, 6);\n" 917348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 917448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 917548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine uniform subroutineTypeTE function;\n" 917648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 917748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "in TC_DATA\n" 917848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 917948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " vec4 tc_data;\n" 918048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " vec4 vs_data;\n" 918148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "} tc[];\n" 918248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 918348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "out TE_DATA\n" 918448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 918548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " vec4 tc_data;\n" 918648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " vec4 te_data;\n" 918748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " vec4 vs_data;\n" 918848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "} result;\n" 918948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 919048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void main()\n" 919148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 919248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " result.vs_data = tc[0].vs_data;\n" 919348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " result.tc_data = tc[0].tc_data;\n" 919448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " function(result.te_data);\n" 919548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n"; 919648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 919748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 919848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Retrieves body of a vertex shader that should be used by the test program. 919948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 920048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return Requested string. 920148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 920248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosstd::string FunctionalTest17::getVertexShaderBody() const 920348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 920448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return "#version 400\n" 920548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 920648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "#extension GL_ARB_shader_subroutine : require\n" 920748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 920848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "out VS_DATA\n" 920948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 921048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " vec4 vs_data;\n" 921148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "} result;\n" 921248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 921348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine void subroutineTypeVS(out vec4 result);\n" 921448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 921548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine(subroutineTypeVS) void subroutine1(out vec4 result)\n" 921648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 921748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " result = vec4(1, 2, 3, 4);\n" 921848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 921948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 922048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine uniform subroutineTypeVS function;\n" 922148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 922248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void main()\n" 922348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 922448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " function(result.vs_data);\n" 922548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n"; 922648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 922748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 922848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Initializes all buffers and GL objects required to run the test. */ 922948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid FunctionalTest17::initTest() 923048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 923148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 923248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 923348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Configure GL_PATCH_VERTICES so that TC only takes a single patch vertex */ 923448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.patchParameteri(GL_PATCH_VERTICES, 1); 923548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glPatchParameteri() call failed."); 923648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 923748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Generate & bind a VAO */ 923848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.genVertexArrays(1, &m_vao_id); 923948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays() call failed."); 924048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 924148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.bindVertexArray(m_vao_id); 924248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() call failed."); 924348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 924448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Set up test program object */ 924548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::string fs_body = getFragmentShaderBody(); 924648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::string gs_body = getGeometryShaderBody(); 924748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::string tc_body = getTessellationControlShaderBody(); 924848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::string te_body = getTessellationEvaluationShaderBody(); 924948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::string vs_body = getVertexShaderBody(); 925048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 925148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!Utils::buildProgram(gl, vs_body, tc_body, te_body, gs_body, fs_body, DE_NULL, /* xfb_varyings */ 925248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos DE_NULL, /* n_xfb_varyings */ 925348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos &m_vs_id, &m_tc_id, &m_te_id, &m_gs_id, &m_fs_id, &m_po_id)) 925448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 925548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos TCU_FAIL("Failed to link test program object"); 925648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 925748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 925848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Set up a texture object that will be used as a color attachment */ 925948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.genTextures(1, &m_to_id); 926048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() call failed."); 926148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 926248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.bindTexture(GL_TEXTURE_2D, m_to_id); 926348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed."); 926448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 926548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.texStorage2D(GL_TEXTURE_2D, 1, /* levels */ 926648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GL_RGBA32F, m_to_width, m_to_height); 926748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2D() call failed."); 926848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 926948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Set up FBO */ 927048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.genFramebuffers(1, &m_fbo_id); 927148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers() call failed."); 927248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 927348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_id); 927448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer() call failed."); 927548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 927648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.framebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_to_id, 0 /* level */); 927748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture2D() call failed."); 927848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 927948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Make sure glReadPixels() does not return misaligned data */ 928048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.pixelStorei(GL_PACK_ALIGNMENT, 1); 928148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glPixelStorei() call failed."); 928248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 928348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Initialize a buffer that will be used to store rendered data */ 928448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_to_data = new float[m_to_width * m_to_height * 4 /* rgba */]; 928548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 928648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 928748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Executes test iteration. 928848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 928948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed. 929048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos */ 929148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulostcu::TestNode::IterateResult FunctionalTest17::iterate() 929248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 929348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 929448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 929548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Do not execute the test if GL_ARB_shader_subroutine is not supported */ 929648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_shader_subroutine")) 929748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 929848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos throw tcu::NotSupportedError("GL_ARB_shader_subroutine is not supported."); 929948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 930048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 930148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos initTest(); 930248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 930348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Use the test program to render a full-screen test quad */ 930448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.useProgram(m_po_id); 930548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed."); 930648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 930748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.drawArrays(GL_PATCHES, 0 /* first */, 1 /* count */); 930848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() call failed."); 930948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 931048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Read back the data that was rendered */ 931148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.readPixels(0, /* x */ 931248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 0, /* y */ 931348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_to_width, m_to_height, GL_RGBA, GL_FLOAT, m_to_data); 931448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glReaDPixels() call failed."); 931548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 931648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Verify the data */ 931748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos verifyRenderedData(); 931848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 931948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /** All done */ 932048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_has_test_passed) 932148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 932248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 932348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 932448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else 932548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 932648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 932748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 932848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 932948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return STOP; 933048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 933148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 933248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Verifies the data that have been rendered by the test program. 933348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 933448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * It is assumed the rendered data have already been copied to 933548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * m_to_data. 933648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 933748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * If the rendered data is found to be invalid, m_has_test_passed 933848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * will be set to false. 933948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 934048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid FunctionalTest17::verifyRenderedData() 934148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 934248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const float epsilon = 1e-5f; 934348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const float expected_data[4] = { 15.0f, 20.0f, 25.0f, 30.0f }; 934448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 934548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (unsigned int y = 0; y < m_to_height && m_has_test_passed; ++y) 934648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 934748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const float* row_ptr = m_to_data + y * 4 /* rgba */ * m_to_width; 934848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 934948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (unsigned int x = 0; x < m_to_width && m_has_test_passed; ++x) 935048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 935148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const float* pixel_ptr = row_ptr + 4 /* rgba */ * x; 935248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 935348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (de::abs(pixel_ptr[0] - expected_data[0]) > epsilon || 935448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos de::abs(pixel_ptr[1] - expected_data[1]) > epsilon || 935548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos de::abs(pixel_ptr[2] - expected_data[2]) > epsilon || 935648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos de::abs(pixel_ptr[3] - expected_data[3]) > epsilon) 935748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 935848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.getLog() << tcu::TestLog::Message << "Invalid texel found at (" << x << ", " << y 935948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << "): " 936048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "expected:(" 936148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << expected_data[0] << ", " << expected_data[1] << ", " << expected_data[2] << ", " 936248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << expected_data[3] << "), found:(" << pixel_ptr[0] << ", " << pixel_ptr[1] << ", " 936348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << pixel_ptr[2] << ", " << pixel_ptr[3] << ")." << tcu::TestLog::EndMessage; 936448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 936548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_has_test_passed = false; 936648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 936748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } /* for (all columns) */ 936848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } /* for (all rows) */ 936948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 937048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 937148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Constructor. 937248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 937348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param context Rendering context. 937448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 937548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 937648087f5f0eb08759ee763f98daf3b34becb74559Pyry HaulosFunctionalTest18_19::FunctionalTest18_19(deqp::Context& context) 937748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos : TestCase(context, "control_flow_and_returned_subroutine_values_used_as_subroutine_input", 937848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "Makes sure that calling a subroutine with argument value returned by " 937948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "another subroutine works correctly. Also checks that subroutine and " 938048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine uniforms work as expected when used in connection with control " 938148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "flow functions.") 938248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_has_test_passed(true) 938348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_n_points_to_draw(16) /* arbitrary value */ 938448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_po_id(0) 938548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_po_subroutine_divide_by_two_location(GL_INVALID_INDEX) 938648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_po_subroutine_multiply_by_four_location(GL_INVALID_INDEX) 938748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_po_subroutine_returns_false_location(GL_INVALID_INDEX) 938848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_po_subroutine_returns_true_location(GL_INVALID_INDEX) 938948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_po_subroutine_uniform_bool_operator1(-1) 939048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_po_subroutine_uniform_bool_operator2(-1) 939148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_po_subroutine_uniform_vec4_processor1(-1) 939248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_po_subroutine_uniform_vec4_processor2(-1) 939348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_xfb_bo_id(0) 939448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_vao_id(0) 939548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_vs_id(0) 939648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 939748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Left blank intentionally */ 939848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 939948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 940048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** De-initializes all GL objects that may have been created during test execution */ 940148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid FunctionalTest18_19::deinit() 940248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 940348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 940448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 940548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_po_id != 0) 940648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 940748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteProgram(m_po_id); 940848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 940948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_po_id = 0; 941048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 941148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 941248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_vao_id != 0) 941348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 941448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteVertexArrays(1, &m_vao_id); 941548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 941648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_vao_id = 0; 941748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 941848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 941948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_vs_id != 0) 942048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 942148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteShader(m_vs_id); 942248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 942348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_vs_id = 0; 942448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 942548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 942648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_xfb_bo_id != 0) 942748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 942848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteBuffers(1, &m_xfb_bo_id); 942948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 943048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_xfb_bo_id = 0; 943148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 943248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 943348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 943448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Executes a single test iteration using user-specified properties. If the 943548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * iterations fails, m_has_test_passed is set to false. 943648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 943748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param bool_operator1_subroutine_location Location of a subroutine to be assigned to 943848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * bool_operator1 subroutine uniform. 943948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param bool_operator2_subroutine_location Location of a subroutine to be assigned to 944048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * bool_operator2 subroutine uniform. 944148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param vec4_operator1_subroutine_location Location of a subroutine to be assigned to 944248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * vec4_operator1 subroutine uniform. 944348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param vec4_operator2_subroutine_location Location of a subroutine to be assigned to 944448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * vec4_operator2 subroutine uniform. 944548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos &**/ 944648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid FunctionalTest18_19::executeTest(glw::GLuint bool_operator1_subroutine_location, 944748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glw::GLuint bool_operator2_subroutine_location, 944848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glw::GLuint vec4_operator1_subroutine_location, 944948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glw::GLuint vec4_operator2_subroutine_location) 945048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 945148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 945248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 945348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Set up subroutines */ 945448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glw::GLuint subroutine_configuration[4 /* total number of subroutines */] = { 0 }; 945548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 945648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos subroutine_configuration[m_po_subroutine_uniform_bool_operator1] = bool_operator1_subroutine_location; 945748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos subroutine_configuration[m_po_subroutine_uniform_bool_operator2] = bool_operator2_subroutine_location; 945848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos subroutine_configuration[m_po_subroutine_uniform_vec4_processor1] = vec4_operator1_subroutine_location; 945948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos subroutine_configuration[m_po_subroutine_uniform_vec4_processor2] = vec4_operator2_subroutine_location; 946048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 946148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.useProgram(m_po_id); 946248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed"); 946348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 946448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.uniformSubroutinesuiv(GL_VERTEX_SHADER, 4 /* count */, subroutine_configuration); 946548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glUniformSubroutinesuiv() call failed"); 946648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 946748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Draw test-specific number of points */ 946848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.beginTransformFeedback(GL_POINTS); 946948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback() call failed"); 947048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 947148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.drawArrays(GL_POINTS, 0 /* first */, m_n_points_to_draw); 947248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() call failed"); 947348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 947448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.endTransformFeedback(); 947548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback() call failed"); 947648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 947748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Map the BO storage into process space */ 947848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::GLvoid* xfb_data_ptr = gl.mapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY); 947948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBuffer() call failed."); 948048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 948148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos verifyXFBData(xfb_data_ptr, bool_operator1_subroutine_location, bool_operator2_subroutine_location, 948248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos vec4_operator1_subroutine_location, vec4_operator2_subroutine_location); 948348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 948448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Unmap BO storage */ 948548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER); 948648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer() call failed."); 948748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 948848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 948948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Retrieves body of a vertex shader to be used by the test. */ 949048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosstd::string FunctionalTest18_19::getVertexShaderBody() const 949148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 949248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return "#version 400\n" 949348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 949448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine bool bool_processor();\n" 949548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine vec4 vec4_processor(in vec4 iparam);\n" 949648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 949748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine(bool_processor) bool returnsFalse()\n" 949848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 949948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " return false;\n" 950048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 950148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 950248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine(bool_processor) bool returnsTrue()\n" 950348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 950448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " return true;\n" 950548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 950648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 950748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine(vec4_processor) vec4 divideByTwo(in vec4 iparam)\n" 950848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 950948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " return iparam * vec4(0.5);\n" 951048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 951148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 951248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine(vec4_processor) vec4 multiplyByFour(in vec4 iparam)\n" 951348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 951448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " return iparam * vec4(4.0);\n" 951548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 951648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 951748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine uniform bool_processor bool_operator1;\n" 951848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine uniform bool_processor bool_operator2;\n" 951948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine uniform vec4_processor vec4_operator1;\n" 952048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine uniform vec4_processor vec4_operator2;\n" 952148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 952248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "out float result;\n" 952348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 952448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void main()\n" 952548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 952648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " if (bool_operator1() )\n" 952748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " {\n" 952848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " float value = float( (3 * gl_VertexID + 1) * 2);\n" 952948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 953048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " while (bool_operator1() )\n" 953148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " {\n" 953248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " value /= float(gl_VertexID + 2);\n" 953348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 953448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " if (value <= 1.0f) break;\n" 953548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " }\n" 953648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 953748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " result = value;\n" 953848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " }\n" 953948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " else\n" 954048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " {\n" 954148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " vec4 value = vec4(gl_VertexID, gl_VertexID + 1,\n" 954248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " gl_VertexID + 2, gl_VertexID + 3);\n" 954348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 954448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " switch (gl_VertexID % 2)\n" 954548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " {\n" 954648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " case 0:\n" 954748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " {\n" 954848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " for (int iteration = 0; iteration < gl_VertexID && bool_operator2(); ++iteration)\n" 954948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " {\n" 955048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " value = vec4_operator2(vec4_operator1(value));\n" 955148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " }\n" 955248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 955348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " break;\n" 955448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " }\n" 955548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 955648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " case 1:\n" 955748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " {\n" 955848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " for (int iteration = 0; iteration < gl_VertexID * 2; ++iteration)\n" 955948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " {\n" 956048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " value = vec4_operator1(vec4_operator2(value));\n" 956148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " }\n" 956248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 956348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " break;\n" 956448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " }\n" 956548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " }\n" 956648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 956748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " result = value.x + value.y + value.z + value.w;\n" 956848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 956948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " }\n" 957048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n"; 957148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 957248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 957348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Initializes all GL objects required to run the test. */ 957448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid FunctionalTest18_19::initTest() 957548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 957648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 957748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* varyings[1] = { "result" }; 957848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::string vs_body = getVertexShaderBody(); 957948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const unsigned int n_varyings = sizeof(varyings) / sizeof(varyings[0]); 958048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 958148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!Utils::buildProgram(gl, vs_body, "", /* tc_body */ 958248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "", /* te_body */ 958348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "", /* gs_body */ 958448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "", /* fs_body */ 958548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos varyings, n_varyings, &m_vs_id, DE_NULL, /* out_tc_id */ 958648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos DE_NULL, /* out_te_id */ 958748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos DE_NULL, /* out_gs_id */ 958848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos DE_NULL, /* out_fs_id */ 958948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos &m_po_id)) 959048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 959148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos TCU_FAIL("Failed to build test program object"); 959248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 959348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 959448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Retrieve subroutine & subroutine uniform locations */ 959548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_po_subroutine_divide_by_two_location = gl.getSubroutineIndex(m_po_id, GL_VERTEX_SHADER, "divideByTwo"); 959648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_po_subroutine_multiply_by_four_location = gl.getSubroutineIndex(m_po_id, GL_VERTEX_SHADER, "multiplyByFour"); 959748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_po_subroutine_returns_false_location = gl.getSubroutineIndex(m_po_id, GL_VERTEX_SHADER, "returnsFalse"); 959848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_po_subroutine_returns_true_location = gl.getSubroutineIndex(m_po_id, GL_VERTEX_SHADER, "returnsTrue"); 959948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glGetSubroutineIndex() call(s) failed"); 960048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 960148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_po_subroutine_divide_by_two_location == GL_INVALID_INDEX || 960248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_po_subroutine_multiply_by_four_location == GL_INVALID_INDEX || 960348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_po_subroutine_returns_false_location == GL_INVALID_INDEX || 960448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_po_subroutine_returns_true_location == GL_INVALID_INDEX) 960548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 960648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos TCU_FAIL("glGetSubroutineIndex() returned GL_INVALID_INDEX for a valid subroutine"); 960748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 960848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 960948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_po_subroutine_uniform_bool_operator1 = 961048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getSubroutineUniformLocation(m_po_id, GL_VERTEX_SHADER, "bool_operator1"); 961148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_po_subroutine_uniform_bool_operator2 = 961248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getSubroutineUniformLocation(m_po_id, GL_VERTEX_SHADER, "bool_operator2"); 961348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_po_subroutine_uniform_vec4_processor1 = 961448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getSubroutineUniformLocation(m_po_id, GL_VERTEX_SHADER, "vec4_operator1"); 961548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_po_subroutine_uniform_vec4_processor2 = 961648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getSubroutineUniformLocation(m_po_id, GL_VERTEX_SHADER, "vec4_operator2"); 961748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glGetSubroutineUniformLocation() call(s) failed"); 961848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 961948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_po_subroutine_uniform_bool_operator1 == -1 || m_po_subroutine_uniform_bool_operator2 == -1 || 962048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_po_subroutine_uniform_vec4_processor1 == -1 || m_po_subroutine_uniform_vec4_processor2 == -1) 962148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 962248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos TCU_FAIL("glGetSubroutineUniformLocation() returned -1 for an active subroutine uniform"); 962348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 962448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 962548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Set up XFB BO */ 962648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const unsigned int bo_size = static_cast<unsigned int>(sizeof(float) * m_n_points_to_draw); 962748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 962848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.genBuffers(1, &m_xfb_bo_id); 962948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers() call failed."); 963048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 963148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_xfb_bo_id); 963248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() call failed."); 963348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 963448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* index */, m_xfb_bo_id); 963548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase() call failed."); 963648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 963748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, bo_size, DE_NULL /* data */, GL_STATIC_COPY); 963848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() call failed."); 963948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 964048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Set up a VAO */ 964148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.genVertexArrays(1, &m_vao_id); 964248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays() call failed."); 964348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 964448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.bindVertexArray(m_vao_id); 964548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() call failed."); 964648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 964748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 964848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Executes test iteration. 964948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 965048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed. 965148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos */ 965248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulostcu::TestNode::IterateResult FunctionalTest18_19::iterate() 965348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 965448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Do not execute the test if GL_ARB_shader_subroutine is not supported */ 965548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_shader_subroutine")) 965648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 965748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos throw tcu::NotSupportedError("GL_ARB_shader_subroutine is not supported."); 965848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 965948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 966048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Initialize all GL objects required to run the test */ 966148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos initTest(); 966248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 966348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Iterate over all subroutine permutations */ 966448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::GLuint subroutine_bool_operators[] = { m_po_subroutine_returns_false_location, 966548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_po_subroutine_returns_true_location }; 966648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const unsigned int n_subroutine_bool_operators = 966748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos sizeof(subroutine_bool_operators) / sizeof(subroutine_bool_operators[0]); 966848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 966948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::GLuint subroutine_vec4_operators[] = { m_po_subroutine_divide_by_two_location, 967048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_po_subroutine_multiply_by_four_location }; 967148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const unsigned int n_subroutine_vec4_operators = 967248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos sizeof(subroutine_vec4_operators) / sizeof(subroutine_vec4_operators[0]); 967348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 967448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (unsigned int n_subroutine_uniform_bool_operator1 = 0; 967548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos n_subroutine_uniform_bool_operator1 < n_subroutine_bool_operators; ++n_subroutine_uniform_bool_operator1) 967648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 967748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (unsigned int n_subroutine_uniform_bool_operator2 = 0; 967848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos n_subroutine_uniform_bool_operator2 < n_subroutine_bool_operators; ++n_subroutine_uniform_bool_operator2) 967948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 968048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (unsigned int n_subroutine_uniform_vec4_operator1 = 0; 968148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos n_subroutine_uniform_vec4_operator1 < n_subroutine_vec4_operators; 968248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos ++n_subroutine_uniform_vec4_operator1) 968348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 968448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (unsigned int n_subroutine_uniform_vec4_operator2 = 0; 968548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos n_subroutine_uniform_vec4_operator2 < n_subroutine_vec4_operators; 968648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos ++n_subroutine_uniform_vec4_operator2) 968748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 968848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos executeTest(subroutine_bool_operators[n_subroutine_uniform_bool_operator1], 968948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos subroutine_bool_operators[n_subroutine_uniform_bool_operator2], 969048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos subroutine_vec4_operators[n_subroutine_uniform_vec4_operator1], 969148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos subroutine_vec4_operators[n_subroutine_uniform_vec4_operator2]); 969248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } /* for (all subroutine vec4 operator subroutines used for processor2) */ 969348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } /* for (all subroutine vec4 operator subroutines used for processor1) */ 969448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } /* for (all subroutine bool operator subroutines used for operator2) */ 969548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } /* for (all subroutine bool operator subroutines used for operator1) */ 969648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 969748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* All done */ 969848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_has_test_passed) 969948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 970048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 970148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 970248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else 970348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 970448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 970548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 970648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 970748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return STOP; 970848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 970948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 971048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Divides input argument by two. The result value is returned to the 971148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * caller. 971248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 971348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param data Input value. 971448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 971548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return As per description. 971648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 971748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulostcu::Vec4 FunctionalTest18_19::vec4operator_div2(tcu::Vec4 data) 971848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 971948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return data * 0.5f; 972048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 972148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 972248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Multiplies input argument by four. The result value is returned to the 972348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * caller. 972448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 972548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param data Input value. 972648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 972748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return As per description. 972848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 972948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulostcu::Vec4 FunctionalTest18_19::vec4operator_mul4(tcu::Vec4 data) 973048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 973148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return data * 4.0f; 973248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 973348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 973448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Verifies data XFBed out by the vertex shader. It is assumed the subroutines were configured 973548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * as per passed arguments, prior to the draw call. 973648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 973748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * If the result data is found to be invalid, m_has_test_passed is set to false. 973848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 973948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param data XFBed data. 974048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param bool_operator1_subroutine_location Location of a subroutine to be assigned to 974148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * bool_operator1 subroutine uniform. 974248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param bool_operator2_subroutine_location Location of a subroutine to be assigned to 974348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * bool_operator2 subroutine uniform. 974448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param vec4_operator1_subroutine_location Location of a subroutine to be assigned to 974548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * vec4_operator1 subroutine uniform. 974648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param vec4_operator2_subroutine_location Location of a subroutine to be assigned to 974748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * vec4_operator2 subroutine uniform. 974848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos */ 974948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid FunctionalTest18_19::verifyXFBData(const glw::GLvoid* data, glw::GLuint bool_operator1_subroutine_location, 975048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glw::GLuint bool_operator2_subroutine_location, 975148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glw::GLuint vec4_operator1_subroutine_location, 975248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glw::GLuint vec4_operator2_subroutine_location) 975348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 975448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos bool bool_operator1_result = false; 975548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos bool bool_operator2_result = false; 975648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const float epsilon = 1e-5f; 975748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos PFNVEC4OPERATORPROC pVec4Operator1 = NULL; 975848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos PFNVEC4OPERATORPROC pVec4Operator2 = NULL; 975948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::GLfloat* traveller_ptr = (const glw::GLfloat*)data; 976048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 976148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos bool_operator1_result = (bool_operator1_subroutine_location == m_po_subroutine_returns_true_location); 976248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos bool_operator2_result = (bool_operator2_subroutine_location == m_po_subroutine_returns_true_location); 976348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos pVec4Operator1 = (vec4_operator1_subroutine_location == m_po_subroutine_divide_by_two_location) ? 976448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos vec4operator_div2 : 976548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos vec4operator_mul4; 976648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos pVec4Operator2 = (vec4_operator2_subroutine_location == m_po_subroutine_divide_by_two_location) ? 976748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos vec4operator_div2 : 976848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos vec4operator_mul4; 976948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 977048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (unsigned int n_vertex = 0; n_vertex < m_n_points_to_draw; ++n_vertex) 977148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 977248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos float expected_value = 0.0f; 977348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 977448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (bool_operator1_result) 977548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 977648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos float value = float((3 * n_vertex + 1) * 2); 977748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 977848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos while (bool_operator1_result) 977948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 978048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos value /= float(n_vertex + 2); 978148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 978248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (value <= 1.0f) 978348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 978448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 978548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 978648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos expected_value = value; 978748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 978848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else 978948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 979048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos tcu::Vec4 value((float)n_vertex, (float)n_vertex + 1, (float)n_vertex + 2, (float)n_vertex + 3); 979148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 979248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos switch (n_vertex % 2) 979348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 979448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case 0: 979548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 979648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (unsigned int iteration = 0; iteration < n_vertex && bool_operator2_result; ++iteration) 979748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 979848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos value = pVec4Operator2(pVec4Operator1(value)); 979948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 980048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 980148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 980248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 980348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 980448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case 1: 980548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 980648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (unsigned int iteration = 0; iteration < n_vertex * 2; ++iteration) 980748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 980848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos value = pVec4Operator1(pVec4Operator2(value)); 980948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 981048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 981148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 981248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 981348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } /* switch (n_vertex % 2) */ 981448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 981548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos expected_value = value.x() + value.y() + value.z() + value.w(); 981648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 981748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 981848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (de::abs(expected_value - *traveller_ptr) > epsilon) 981948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 982048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.getLog() << tcu::TestLog::Message << "XFBed data was found to be invalid at index [" << n_vertex 982148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << "]" 982248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "for the following subroutine location configuration:" 982348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " bool_operator1_subroutine_location:[" 982448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << bool_operator1_subroutine_location << "]" 982548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " bool_operator2_subroutine_location:[" 982648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << bool_operator2_subroutine_location << "]" 982748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " vec4_operator1_subroutine_location:[" 982848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << vec4_operator1_subroutine_location << "]" 982948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " vec4_operator2_subroutine_location:[" 983048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << vec4_operator2_subroutine_location << "];" 983148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " expected data:" 983248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << expected_value << ", found:" << *traveller_ptr << tcu::TestLog::EndMessage; 983348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 983448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_has_test_passed = false; 983548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 983648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 983748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos ++traveller_ptr; 983848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } /* for (all drawn points) */ 983948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 984048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 984148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/* Constants used by FunctionalTest20_21 */ 984248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosconst GLuint FunctionalTest20_21::m_n_shared_contexts = 4; 984348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosconst GLuint FunctionalTest20_21::m_fragment_stage_index = 0; 984448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosconst GLuint FunctionalTest20_21::m_geometry_stage_index = 1; 984548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosconst GLuint FunctionalTest20_21::m_tesselation_control_stage_index = 2; 984648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosconst GLuint FunctionalTest20_21::m_tesselation_evaluation_stage_index = 3; 984748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosconst GLuint FunctionalTest20_21::m_vertex_stage_index = 4; 984848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 984948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Set subroutine indices, indices are taken from one of two sets according to provided <bit_field> 985048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 985148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param bit_field Selects source of of index for each stage 985248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param subroutine_indices Array of two indices sets 985348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 985448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid FunctionalTest20_21::subroutineUniformSet::set(GLuint bit_field, const subroutineUniformSet subroutine_indices[2]) 985548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 985648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint vertex_stage = ((bit_field & (0x01 << 0)) >> 0); 985748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint tesselation_control_stage = ((bit_field & (0x01 << 1)) >> 1); 985848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint tesselation_evaluation_stage = ((bit_field & (0x01 << 2)) >> 2); 985948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint geometry_stage = ((bit_field & (0x01 << 3)) >> 3); 986048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint fragment_stage = ((bit_field & (0x01 << 4)) >> 4); 986148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 986248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_vertex_shader_stage = subroutine_indices[vertex_stage].m_vertex_shader_stage; 986348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_tesselation_control_shader_stage = 986448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos subroutine_indices[tesselation_control_stage].m_tesselation_control_shader_stage; 986548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_tesselation_evaluation_shader_stage = 986648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos subroutine_indices[tesselation_evaluation_stage].m_tesselation_evaluation_shader_stage; 986748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_geometry_shader_stage = subroutine_indices[geometry_stage].m_geometry_shader_stage; 986848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_fragment_shader_stage = subroutine_indices[fragment_stage].m_fragment_shader_stage; 986948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 987048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 987148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Negated comparison of two sets 987248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 987348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param arg Instance that will be compared to this 987448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 987548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return false when both objects are equal, true otherwise 987648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 987748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosbool FunctionalTest20_21::subroutineUniformSet::operator!=(const subroutineUniformSet& arg) const 987848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 987948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if ((arg.m_vertex_shader_stage != m_vertex_shader_stage) || 988048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos (arg.m_tesselation_control_shader_stage != m_tesselation_control_shader_stage) || 988148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos (arg.m_tesselation_evaluation_shader_stage != m_tesselation_evaluation_shader_stage) || 988248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos (arg.m_geometry_shader_stage != m_geometry_shader_stage) || 988348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos (arg.m_fragment_shader_stage != m_fragment_shader_stage)) 988448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 988548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return true; 988648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 988748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 988848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return false; 988948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 989048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 989148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Constructor. 989248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 989348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param context Rendering context. 989448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 989548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 989648087f5f0eb08759ee763f98daf3b34becb74559Pyry HaulosFunctionalTest20_21::FunctionalTest20_21(deqp::Context& context) 989748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos : TestCase(context, "multiple_contexts", 989848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "Verifies that shader uniforms are preserved when rendering context is switched.") 989948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 990048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLuint i = 0; i < m_n_shared_contexts + 1; ++i) 990148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 990248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_program_pipelines[i] = 0; 990348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 990448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 990548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLuint i = 0; i < m_n_shared_contexts; ++i) 990648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 990748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_shared_contexts[i] = 0; 990848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 990948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 991048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 991148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Deinitializes all GL objects that may have been created during 991248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * test execution. 991348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 991448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid FunctionalTest20_21::deinit() 991548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 991648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* GL entry points */ 991748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 991848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 991948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLuint i = 0; i < m_n_shared_contexts + 1; ++i) 992048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 992148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (0 != m_program_pipelines[i]) 992248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 992348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteProgramPipelines(1, &m_program_pipelines[i]); 992448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_program_pipelines[i] = 0; 992548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 992648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 992748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 992848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLuint i = 0; i < m_n_shared_contexts; ++i) 992948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 993048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (0 != m_shared_contexts[i]) 993148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 993248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos delete m_shared_contexts[i]; 993348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_shared_contexts[i] = 0; 993448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 993548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 993648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 993748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_context.getRenderContext().makeCurrent(); 993848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 993948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 994048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Executes test iteration. 994148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 994248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return Returns STOP 994348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos */ 994448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulostcu::TestNode::IterateResult FunctionalTest20_21::iterate() 994548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 994648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Do not execute the test if GL_ARB_shader_subroutine is not supported */ 994748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_shader_subroutine")) 994848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 994948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos throw tcu::NotSupportedError("GL_ARB_shader_subroutine is not supported."); 995048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 995148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 995248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Test cases, values stored here are used as bit fields */ 995348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLuint test_cases[][m_n_shared_contexts + 1] = { 995448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 0, 1, 2, 3, 4 }, { 1, 2, 3, 4, 0 }, { 2, 3, 4, 0, 1 }, { 3, 4, 0, 1, 2 }, 995548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 4, 0, 1, 2, 3 }, { 27, 28, 29, 30, 31 }, { 28, 29, 30, 31, 27 }, { 29, 30, 31, 27, 28 }, 995648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 30, 31, 27, 28, 29 }, { 31, 27, 28, 29, 30 }, 995748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos }; 995848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLuint n_test_cases = sizeof(test_cases) / sizeof(test_cases[0]); 995948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 996048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Prepare contexts */ 996148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos initSharedContexts(); 996248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 996348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Test result */ 996448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos bool result = true; 996548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 996648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Program pointers */ 996748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::program* program_pointers[5]; 996848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 996948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Test monolithic program */ 997048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 997148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Prepare program */ 997248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::program program(m_context); 997348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 997448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos program_pointers[m_fragment_stage_index] = &program; 997548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 997648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos prepareProgram(program_pointers, false); 997748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 997848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Execute test */ 997948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (false == testProgram(program_pointers, false, test_cases, n_test_cases)) 998048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 998148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_context.getTestContext().getLog() << tcu::TestLog::Message 998248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << "Last error message was caused by monolithic program." 998348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << tcu::TestLog::EndMessage; 998448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 998548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = false; 998648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 998748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 998848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 998948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Test separable programs */ 999048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (true == m_context.getContextInfo().isExtensionSupported("GL_ARB_separate_shader_objects")) 999148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 999248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Prepare programs */ 999348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::program vertex_program(m_context); 999448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::program tesselation_control_program(m_context); 999548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::program tesselation_evaluation_program(m_context); 999648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::program geometry_program(m_context); 999748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::program fragment_program(m_context); 999848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 999948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos program_pointers[m_fragment_stage_index] = &fragment_program; 1000048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos program_pointers[m_geometry_stage_index] = &geometry_program; 1000148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos program_pointers[m_tesselation_control_stage_index] = &tesselation_control_program; 1000248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos program_pointers[m_tesselation_evaluation_stage_index] = &tesselation_evaluation_program; 1000348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos program_pointers[m_vertex_stage_index] = &vertex_program; 1000448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1000548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos prepareProgram(program_pointers, true); 1000648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1000748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Execute test */ 1000848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (false == testProgram(program_pointers, true, test_cases, n_test_cases)) 1000948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1001048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_context.getTestContext().getLog() << tcu::TestLog::Message 1001148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << "Last error message was caused by separable program." 1001248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << tcu::TestLog::EndMessage; 1001348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = false; 1001448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1001548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1001648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1001748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* All done */ 1001848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (true == result) 1001948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1002048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 1002148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1002248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else 1002348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1002448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 1002548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1002648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1002748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return tcu::TestNode::STOP; 1002848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 1002948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1003048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Query state of subroutine uniforms of current program/pipeline 1003148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1003248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param set Storage for results 1003348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 1003448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid FunctionalTest20_21::captureCurrentSubroutineSet(subroutineUniformSet& set) 1003548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 1003648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* GL entry points */ 1003748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1003848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1003948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Fragment */ 1004048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getUniformSubroutineuiv(GL_FRAGMENT_SHADER, m_subroutine_uniform_locations.m_fragment_shader_stage, 1004148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos &set.m_fragment_shader_stage); 1004248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "GetUniformSubroutineuiv"); 1004348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1004448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Geometry */ 1004548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getUniformSubroutineuiv(GL_GEOMETRY_SHADER, m_subroutine_uniform_locations.m_geometry_shader_stage, 1004648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos &set.m_geometry_shader_stage); 1004748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "GetUniformSubroutineuiv"); 1004848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1004948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Tess ctrl */ 1005048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getUniformSubroutineuiv(GL_TESS_CONTROL_SHADER, 1005148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_subroutine_uniform_locations.m_tesselation_control_shader_stage, 1005248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos &set.m_tesselation_control_shader_stage); 1005348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "GetUniformSubroutineuiv"); 1005448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1005548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Tess eval */ 1005648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getUniformSubroutineuiv(GL_TESS_EVALUATION_SHADER, 1005748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_subroutine_uniform_locations.m_tesselation_evaluation_shader_stage, 1005848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos &set.m_tesselation_evaluation_shader_stage); 1005948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "GetUniformSubroutineuiv"); 1006048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1006148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Vertex */ 1006248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getUniformSubroutineuiv(GL_VERTEX_SHADER, m_subroutine_uniform_locations.m_vertex_shader_stage, 1006348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos &set.m_vertex_shader_stage); 1006448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "GetUniformSubroutineuiv"); 1006548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 1006648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1006748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Get shaders' source code 1006848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1006948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param out_vertex_shader_code Vertex source code 1007048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param out_tesselation_control_shader_code Tess ctrl source code 1007148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param out_tesselation_evaluation_shader_code Tess eval source code 1007248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param out_geometry_shader_code Geometry source code 1007348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param out_fragment_shader_code Fragment source code 1007448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 1007548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid FunctionalTest20_21::getShaders(const glw::GLchar*& out_vertex_shader_code, 1007648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::GLchar*& out_tesselation_control_shader_code, 1007748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::GLchar*& out_tesselation_evaluation_shader_code, 1007848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::GLchar*& out_geometry_shader_code, 1007948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::GLchar*& out_fragment_shader_code) 1008048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 1008148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLchar* vertex_shader_code = "#version 400 core\n" 1008248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "#extension GL_ARB_shader_subroutine : require\n" 1008348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1008448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "precision highp float;\n" 1008548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1008648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "// Subroutine type\n" 1008748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine vec4 routine_type(in vec4 left, in vec4 right);\n" 1008848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1008948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "// Subroutine definition\n" 1009048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine(routine_type) vec4 add(in vec4 left, in vec4 right)\n" 1009148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 1009248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " return left + right;\n" 1009348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 1009448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1009548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine(routine_type) vec4 multiply(in vec4 left, in vec4 right)\n" 1009648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 1009748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " return left * right;\n" 1009848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 1009948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1010048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "// Sub routine uniform\n" 1010148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine uniform routine_type routine;\n" 1010248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1010348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "// Input data\n" 1010448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "uniform vec4 uni_vs_left;\n" 1010548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "uniform vec4 uni_vs_right;\n" 1010648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1010748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "// Output\n" 1010848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "out vec4 vs_tcs_result;\n" 1010948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1011048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void main()\n" 1011148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 1011248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " vs_tcs_result = routine(uni_vs_left, uni_vs_right);\n" 1011348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 1011448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n"; 1011548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1011648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLchar* tesselation_control_shader_code = 1011748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "#version 400 core\n" 1011848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "#extension GL_ARB_shader_subroutine : require\n" 1011948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1012048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "precision highp float;\n" 1012148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1012248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "layout(vertices = 1) out;\n" 1012348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1012448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "// Subroutine type\n" 1012548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine vec4 routine_type(in vec4 left, in vec4 right);\n" 1012648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1012748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "// Subroutine definition\n" 1012848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine(routine_type) vec4 add(in vec4 left, in vec4 right)\n" 1012948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 1013048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " return left + right;\n" 1013148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 1013248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1013348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine(routine_type) vec4 multiply(in vec4 left, in vec4 right)\n" 1013448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 1013548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " return left * right;\n" 1013648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 1013748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1013848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "// Sub routine uniform\n" 1013948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine uniform routine_type routine;\n" 1014048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1014148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "// Input data\n" 1014248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "uniform vec4 uni_tcs_left;\n" 1014348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "uniform vec4 uni_tcs_right;\n" 1014448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1014548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "in vec4 vs_tcs_result[];\n" 1014648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1014748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "// Output\n" 1014848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "out vec4 tcs_tes_result[];\n" 1014948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1015048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void main()\n" 1015148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 1015248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " gl_TessLevelOuter[0] = 1.0;\n" 1015348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " gl_TessLevelOuter[1] = 1.0;\n" 1015448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " gl_TessLevelOuter[2] = 1.0;\n" 1015548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " gl_TessLevelOuter[3] = 1.0;\n" 1015648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " gl_TessLevelInner[0] = 1.0;\n" 1015748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " gl_TessLevelInner[1] = 1.0;\n" 1015848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1015948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " tcs_tes_result[gl_InvocationID] = routine(uni_tcs_left, uni_tcs_right) + vs_tcs_result[gl_InvocationID];\n" 1016048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 1016148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n"; 1016248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1016348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLchar* tesselation_evaluation_shader_code = 1016448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "#version 400 core\n" 1016548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "#extension GL_ARB_shader_subroutine : require\n" 1016648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1016748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "precision highp float;\n" 1016848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1016948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "layout(isolines, point_mode) in;\n" 1017048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1017148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "// Subroutine type\n" 1017248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine vec4 routine_type(in vec4 left, in vec4 right);\n" 1017348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1017448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "// Subroutine definition\n" 1017548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine(routine_type) vec4 add(in vec4 left, in vec4 right)\n" 1017648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 1017748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " return left + right;\n" 1017848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 1017948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1018048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine(routine_type) vec4 multiply(in vec4 left, in vec4 right)\n" 1018148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 1018248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " return left * right;\n" 1018348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 1018448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1018548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "// Sub routine uniform\n" 1018648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine uniform routine_type routine;\n" 1018748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1018848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "// Input data\n" 1018948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "uniform vec4 uni_tes_left;\n" 1019048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "uniform vec4 uni_tes_right;\n" 1019148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1019248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "in vec4 tcs_tes_result[];\n" 1019348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1019448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "// Output\n" 1019548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "out vec4 tes_gs_result;\n" 1019648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1019748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void main()\n" 1019848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 1019948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " tes_gs_result = routine(uni_tes_left, uni_tes_right) + tcs_tes_result[0];\n" 1020048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 1020148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n"; 1020248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1020348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLchar* geometry_shader_code = 1020448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "#version 400 core\n" 1020548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "#extension GL_ARB_shader_subroutine : require\n" 1020648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1020748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "precision highp float;\n" 1020848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1020948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "layout(points) in;\n" 1021048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "layout(points, max_vertices = 1) out;\n" 1021148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1021248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "// Subroutine type\n" 1021348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine vec4 routine_type(in vec4 left, in vec4 right);\n" 1021448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1021548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "// Subroutine definition\n" 1021648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine(routine_type) vec4 add(in vec4 left, in vec4 right)\n" 1021748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 1021848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " return left + right;\n" 1021948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 1022048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1022148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine(routine_type) vec4 multiply(in vec4 left, in vec4 right)\n" 1022248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 1022348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " return left * right;\n" 1022448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 1022548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1022648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "// Sub routine uniform\n" 1022748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine uniform routine_type routine;\n" 1022848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1022948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "// Input data\n" 1023048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "uniform vec4 uni_gs_left;\n" 1023148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "uniform vec4 uni_gs_right;\n" 1023248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1023348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "in vec4 tes_gs_result[];\n" 1023448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1023548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "// Output\n" 1023648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "out vec4 gs_fs_result;\n" 1023748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1023848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void main()\n" 1023948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 1024048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " gs_fs_result = routine(uni_gs_left, uni_gs_right) + tes_gs_result[0];\n" 1024148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 1024248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n"; 1024348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1024448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLchar* fragmenty_shader_code = 1024548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "#version 400 core\n" 1024648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "#extension GL_ARB_shader_subroutine : require\n" 1024748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1024848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "precision highp float;\n" 1024948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1025048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "// Subroutine type\n" 1025148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine vec4 routine_type(in vec4 left, in vec4 right);\n" 1025248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1025348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "// Subroutine definition\n" 1025448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine(routine_type) vec4 add(in vec4 left, in vec4 right)\n" 1025548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 1025648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " return left + right;\n" 1025748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 1025848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1025948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine(routine_type) vec4 multiply(in vec4 left, in vec4 right)\n" 1026048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 1026148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " return left * right;\n" 1026248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 1026348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1026448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "// Sub routine uniform\n" 1026548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine uniform routine_type routine;\n" 1026648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1026748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "// Input data\n" 1026848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "uniform vec4 uni_fs_left;\n" 1026948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "uniform vec4 uni_fs_right;\n" 1027048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1027148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "in vec4 gs_fs_result;\n" 1027248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1027348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "// Output\n" 1027448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "out vec4 fs_out_result;\n" 1027548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1027648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void main()\n" 1027748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 1027848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " fs_out_result = routine(uni_fs_left, uni_fs_right) + gs_fs_result;\n" 1027948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 1028048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n"; 1028148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1028248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos out_vertex_shader_code = vertex_shader_code; 1028348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos out_tesselation_control_shader_code = tesselation_control_shader_code; 1028448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos out_tesselation_evaluation_shader_code = tesselation_evaluation_shader_code; 1028548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos out_geometry_shader_code = geometry_shader_code; 1028648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos out_fragment_shader_code = fragmenty_shader_code; 1028748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 1028848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1028948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Create <m_n_shared_contexts> shared contexts 1029048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1029148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 1029248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid FunctionalTest20_21::initSharedContexts() 1029348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 1029448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLuint i = 0; i < m_n_shared_contexts; ++i) 1029548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1029648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_shared_contexts[i] = m_context.createSharedContext(); 1029748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1029848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 1029948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1030048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Prepare program(s) 1030148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1030248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param programs An array of 5 programs' pointers. If monolithic program is prepared that only index m_fragment_stage_index should be initialized, otherwise all 5 1030348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param is_separable Select if monolithic or separable programs should be prepared 1030448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 1030548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid FunctionalTest20_21::prepareProgram(Utils::program** programs, bool is_separable) 1030648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 1030748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Get shader sources */ 1030848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLchar* vertex_shader_code; 1030948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLchar* tesselation_control_shader_code; 1031048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLchar* tesselation_evaluation_shader_code; 1031148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLchar* geometry_shader_code; 1031248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const GLchar* fragmenty_shader_code; 1031348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1031448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos getShaders(vertex_shader_code, tesselation_control_shader_code, tesselation_evaluation_shader_code, 1031548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos geometry_shader_code, fragmenty_shader_code); 1031648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1031748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Subroutines and uniform names */ 1031848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLchar* subroutine_names[] = { "add", "multiply" }; 1031948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLuint n_subroutines = sizeof(subroutine_names) / sizeof(subroutine_names[0]); 1032048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1032148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLchar* subroutine_uniform_name = "routine"; 1032248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1032348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Build program */ 1032448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (false == is_separable) 1032548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1032648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos programs[0]->build(0 /* compute shader source */, fragmenty_shader_code, geometry_shader_code, 1032748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos tesselation_control_shader_code, tesselation_evaluation_shader_code, vertex_shader_code, 1032848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 0 /* varying_names */, 0 /* n_varying_names */); 1032948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1033048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos programs[m_geometry_stage_index] = programs[m_fragment_stage_index]; 1033148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos programs[m_tesselation_control_stage_index] = programs[m_fragment_stage_index]; 1033248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos programs[m_tesselation_evaluation_stage_index] = programs[m_fragment_stage_index]; 1033348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos programs[m_vertex_stage_index] = programs[m_fragment_stage_index]; 1033448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1033548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else 1033648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1033748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos programs[m_fragment_stage_index]->build(0, fragmenty_shader_code, 0, 0, 0, 0, 0, 0, true); 1033848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos programs[m_geometry_stage_index]->build(0, 0, geometry_shader_code, 0, 0, 0, 0, 0, true); 1033948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos programs[m_tesselation_control_stage_index]->build(0, 0, 0, tesselation_control_shader_code, 0, 0, 0, 0, true); 1034048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos programs[m_tesselation_evaluation_stage_index]->build(0, 0, 0, 0, tesselation_evaluation_shader_code, 0, 0, 0, 1034148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos true); 1034248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos programs[m_vertex_stage_index]->build(0, 0, 0, 0, 0, vertex_shader_code, 0, 0, true); 1034348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1034448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1034548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Get subroutine indices */ 1034648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLuint i = 0; i < n_subroutines; ++i) 1034748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1034848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_subroutine_indices[i].m_fragment_shader_stage = 1034948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos programs[m_fragment_stage_index]->getSubroutineIndex(subroutine_names[i], GL_FRAGMENT_SHADER); 1035048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1035148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_subroutine_indices[i].m_geometry_shader_stage = 1035248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos programs[m_geometry_stage_index]->getSubroutineIndex(subroutine_names[i], GL_GEOMETRY_SHADER); 1035348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1035448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_subroutine_indices[i].m_tesselation_control_shader_stage = 1035548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos programs[m_tesselation_control_stage_index]->getSubroutineIndex(subroutine_names[i], 1035648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GL_TESS_CONTROL_SHADER); 1035748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1035848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_subroutine_indices[i].m_tesselation_evaluation_shader_stage = 1035948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos programs[m_tesselation_evaluation_stage_index]->getSubroutineIndex(subroutine_names[i], 1036048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GL_TESS_EVALUATION_SHADER); 1036148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1036248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_subroutine_indices[i].m_vertex_shader_stage = 1036348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos programs[m_vertex_stage_index]->getSubroutineIndex(subroutine_names[i], GL_VERTEX_SHADER); 1036448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1036548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1036648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Get subroutine uniform locations */ 1036748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_subroutine_uniform_locations.m_fragment_shader_stage = 1036848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos programs[m_fragment_stage_index]->getSubroutineUniformLocation(subroutine_uniform_name, GL_FRAGMENT_SHADER); 1036948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1037048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_subroutine_uniform_locations.m_geometry_shader_stage = 1037148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos programs[m_geometry_stage_index]->getSubroutineUniformLocation(subroutine_uniform_name, GL_GEOMETRY_SHADER); 1037248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1037348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_subroutine_uniform_locations.m_tesselation_control_shader_stage = 1037448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos programs[m_tesselation_control_stage_index]->getSubroutineUniformLocation(subroutine_uniform_name, 1037548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GL_TESS_CONTROL_SHADER); 1037648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1037748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_subroutine_uniform_locations.m_tesselation_evaluation_shader_stage = 1037848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos programs[m_tesselation_evaluation_stage_index]->getSubroutineUniformLocation(subroutine_uniform_name, 1037948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GL_TESS_EVALUATION_SHADER); 1038048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1038148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_subroutine_uniform_locations.m_vertex_shader_stage = 1038248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos programs[m_vertex_stage_index]->getSubroutineUniformLocation(subroutine_uniform_name, GL_VERTEX_SHADER); 1038348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 1038448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1038548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Generate program pipeline for current context and attach separable programs 1038648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1038748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param out_pipeline_id Id of generated pipeline 1038848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param programs Collection of separable programs 1038948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 1039048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid FunctionalTest20_21::prepareProgramPipeline(glw::GLuint& out_pipeline_id, Utils::program** programs) 1039148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 1039248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* GL entry points */ 1039348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1039448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1039548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Generate */ 1039648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.genProgramPipelines(1, &out_pipeline_id); 1039748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "GenProgramPipelines"); 1039848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1039948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Bind */ 1040048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.bindProgramPipeline(out_pipeline_id); 1040148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "BindProgramPipeline"); 1040248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1040348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Set up programs */ 1040448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.useProgramStages(out_pipeline_id, GL_FRAGMENT_SHADER_BIT, programs[m_fragment_stage_index]->m_program_object_id); 1040548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "UseProgramStages"); 1040648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1040748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.useProgramStages(out_pipeline_id, GL_GEOMETRY_SHADER_BIT, programs[m_geometry_stage_index]->m_program_object_id); 1040848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "UseProgramStages"); 1040948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1041048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.useProgramStages(out_pipeline_id, GL_TESS_CONTROL_SHADER_BIT, 1041148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos programs[m_tesselation_control_stage_index]->m_program_object_id); 1041248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "UseProgramStages"); 1041348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1041448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.useProgramStages(out_pipeline_id, GL_TESS_EVALUATION_SHADER_BIT, 1041548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos programs[m_tesselation_evaluation_stage_index]->m_program_object_id); 1041648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "UseProgramStages"); 1041748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1041848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.useProgramStages(out_pipeline_id, GL_VERTEX_SHADER_BIT, programs[m_vertex_stage_index]->m_program_object_id); 1041948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "UseProgramStages"); 1042048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 1042148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1042248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Test specific case 1042348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1042448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param bit_field An array of 5 bit fields used to set up subroutine uniforms, one element per context 1042548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1042648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return True if test pass, false otherwise 1042748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 1042848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosbool FunctionalTest20_21::testCase(const glw::GLuint bit_field[5]) 1042948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 1043048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Storage for subroutine indices */ 1043148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos subroutineUniformSet captured_subroutine_indices[m_n_shared_contexts + 1]; 1043248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos subroutineUniformSet subroutine_indices[m_n_shared_contexts + 1]; 1043348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1043448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Prepare subroutine_indices with bit fields */ 1043548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLuint i = 0; i < m_n_shared_contexts + 1; ++i) 1043648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1043748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos subroutine_indices[i].set(bit_field[i], m_subroutine_indices); 1043848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos }; 1043948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1044048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Update subroutine uniforms, each context gets different set */ 1044148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLuint i = 0; i < m_n_shared_contexts; ++i) 1044248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1044348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_shared_contexts[i]->makeCurrent(); 1044448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos updateCurrentSubroutineSet(subroutine_indices[i]); 1044548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1044648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1044748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_context.getRenderContext().makeCurrent(); 1044848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos updateCurrentSubroutineSet(subroutine_indices[m_n_shared_contexts]); 1044948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1045048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Capture subroutine uniforms */ 1045148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLuint i = 0; i < m_n_shared_contexts; ++i) 1045248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1045348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_shared_contexts[i]->makeCurrent(); 1045448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos captureCurrentSubroutineSet(captured_subroutine_indices[i]); 1045548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1045648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1045748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_context.getRenderContext().makeCurrent(); 1045848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos captureCurrentSubroutineSet(captured_subroutine_indices[m_n_shared_contexts]); 1045948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1046048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Verify that captured uniforms match expected values */ 1046148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLuint i = 0; i < m_n_shared_contexts + 1; ++i) 1046248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1046348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (subroutine_indices[i] != captured_subroutine_indices[i]) 1046448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1046548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_context.getTestContext().getLog() 1046648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << tcu::TestLog::Message << "Error." 1046748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << " Context: " << i << " VS, expected: " << subroutine_indices[i].m_vertex_shader_stage 1046848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << " captured: " << captured_subroutine_indices[i].m_vertex_shader_stage 1046948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << " TCS, expected: " << subroutine_indices[i].m_tesselation_control_shader_stage 1047048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << " captured: " << captured_subroutine_indices[i].m_tesselation_control_shader_stage 1047148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << " TES, expected: " << subroutine_indices[i].m_tesselation_evaluation_shader_stage 1047248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << " captured: " << captured_subroutine_indices[i].m_tesselation_evaluation_shader_stage 1047348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << " GS, expected: " << subroutine_indices[i].m_geometry_shader_stage 1047448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << " captured: " << captured_subroutine_indices[i].m_geometry_shader_stage 1047548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << " FS, expected: " << subroutine_indices[i].m_fragment_shader_stage 1047648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << " captured: " << captured_subroutine_indices[i].m_fragment_shader_stage << tcu::TestLog::EndMessage; 1047748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1047848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return false; 1047948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1048048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1048148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1048248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return true; 1048348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 1048448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1048548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Test a program or pipeline 1048648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1048748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param programs An array of 5 programs\ pointers, as in preparePrograms 1048848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param is_separable Selects if monolithic or separable programs should be used 1048948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param test_cases Collection of test cases 1049048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param n_test_cases Number of test cases 1049148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1049248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return True if all cases pass, false otherwise 1049348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 1049448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosbool FunctionalTest20_21::testProgram(Utils::program** programs, bool is_separable, const glw::GLuint test_cases[][5], 1049548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glw::GLuint n_test_cases) 1049648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 1049748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Set program/pipeline as current for all contexts */ 1049848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (false == is_separable) 1049948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1050048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos programs[0]->use(); 1050148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1050248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLuint i = 0; i < m_n_shared_contexts; ++i) 1050348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1050448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_shared_contexts[i]->makeCurrent(); 1050548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos programs[0]->use(); 1050648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1050748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1050848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else 1050948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1051048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* GL entry points */ 1051148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1051248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1051348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Make sure that program pipeline will be used */ 1051448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.useProgram(0); 1051548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "UseProgram"); 1051648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1051748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos prepareProgramPipeline(m_program_pipelines[m_n_shared_contexts], programs); 1051848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1051948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLuint i = 0; i < m_n_shared_contexts; ++i) 1052048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1052148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_shared_contexts[i]->makeCurrent(); 1052248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1052348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Make sure that program pipeline will be used */ 1052448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.useProgram(0); 1052548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "UseProgram"); 1052648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1052748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos prepareProgramPipeline(m_program_pipelines[i], programs); 1052848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1052948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1053048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1053148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Execute test */ 1053248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos bool result = true; 1053348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (GLuint i = 0; i < n_test_cases; ++i) 1053448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1053548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (false == testCase(test_cases[i])) 1053648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1053748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = false; 1053848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 1053948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1054048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1054148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1054248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return result; 1054348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 1054448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1054548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Set up subroutine uniforms for current program or pipeline 1054648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1054748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param set Set of subroutine indices 1054848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 1054948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid FunctionalTest20_21::updateCurrentSubroutineSet(const subroutineUniformSet& set) 1055048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 1055148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* GL entry points */ 1055248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1055348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1055448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Fragment */ 1055548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.uniformSubroutinesuiv(GL_FRAGMENT_SHADER, 1 /* count */, &set.m_fragment_shader_stage); 1055648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "UniformSubroutinesuiv"); 1055748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1055848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Geometry */ 1055948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.uniformSubroutinesuiv(GL_GEOMETRY_SHADER, 1 /* count */, &set.m_geometry_shader_stage); 1056048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "UniformSubroutinesuiv"); 1056148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1056248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Tess ctrl */ 1056348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.uniformSubroutinesuiv(GL_TESS_CONTROL_SHADER, 1 /* count */, &set.m_tesselation_control_shader_stage); 1056448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "UniformSubroutinesuiv"); 1056548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1056648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Tess eval */ 1056748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.uniformSubroutinesuiv(GL_TESS_EVALUATION_SHADER, 1 /* count */, &set.m_tesselation_evaluation_shader_stage); 1056848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "UniformSubroutinesuiv"); 1056948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1057048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Vertex */ 1057148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.uniformSubroutinesuiv(GL_VERTEX_SHADER, 1 /* count */, &set.m_vertex_shader_stage); 1057248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "UniformSubroutinesuiv"); 1057348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 1057448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1057548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Constructor. 1057648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1057748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param context Rendering context. 1057848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1057948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 1058048087f5f0eb08759ee763f98daf3b34becb74559Pyry HaulosNegativeTest1::NegativeTest1(deqp::Context& context) 1058148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos : TestCase(context, "subroutine_errors", "Verifies all GL_INVALID_OPERATION, GL_INVALID_VALUE, GL_INVALID ENUM " 1058248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "errors related to subroutine usage are properly generated.") 1058348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_has_test_passed(true) 1058448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_po_active_subroutine_uniform_locations(0) 1058548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_po_active_subroutine_uniforms(0) 1058648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_po_active_subroutines(0) 1058748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_po_subroutine_uniform_function_index(-1) 1058848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_po_subroutine_uniform_function2_index(-1) 1058948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_po_subroutine_test1_index(GL_INVALID_INDEX) 1059048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_po_subroutine_test2_index(GL_INVALID_INDEX) 1059148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_po_subroutine_test3_index(GL_INVALID_INDEX) 1059248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_po_not_linked_id(0) 1059348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_po_id(0) 1059448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_vs_id(0) 1059548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 1059648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Left blank intentionally */ 1059748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 1059848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1059948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Deinitializes all GL objects that may have been created during 1060048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * test execution. 1060148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 1060248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid NegativeTest1::deinit() 1060348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 1060448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1060548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1060648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_po_id != 0) 1060748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1060848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteProgram(m_po_id); 1060948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1061048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_po_id = 0; 1061148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1061248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1061348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_po_not_linked_id != 0) 1061448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1061548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteProgram(m_po_not_linked_id); 1061648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1061748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_po_not_linked_id = 0; 1061848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1061948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1062048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_vs_id != 0) 1062148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1062248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteShader(m_vs_id); 1062348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1062448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_vs_id = 0; 1062548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1062648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 1062748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1062848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Initializes all GL objects required to run the test. */ 1062948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid NegativeTest1::initTest() 1063048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 1063148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glw::GLint compile_status = GL_FALSE; 1063248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1063348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1063448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Create program objects */ 1063548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_po_not_linked_id = gl.createProgram(); 1063648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_po_id = gl.createProgram(); 1063748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call(s) failed."); 1063848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1063948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Create vertex shader object */ 1064048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_vs_id = gl.createShader(GL_VERTEX_SHADER); 1064148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call failed."); 1064248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1064348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Set up vertex shader */ 1064448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* vs_body = "#version 400\n" 1064548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1064648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "#extension GL_ARB_shader_subroutine : require\n" 1064748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1064848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine void subroutineType (out ivec2 arg);\n" 1064948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine void subroutineType2(out ivec4 arg);\n" 1065048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1065148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine(subroutineType) void test1(out ivec2 arg)\n" 1065248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 1065348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " arg = ivec2(1, 2);\n" 1065448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 1065548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine(subroutineType) void test2(out ivec2 arg)\n" 1065648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 1065748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " arg = ivec2(3,4);\n" 1065848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 1065948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine(subroutineType2) void test3(out ivec4 arg)\n" 1066048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 1066148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " arg = ivec4(1, 2, 3, 4);\n" 1066248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 1066348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1066448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine uniform subroutineType function;\n" 1066548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine uniform subroutineType2 function2;\n" 1066648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1066748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void main()\n" 1066848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 1066948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " ivec2 test;\n" 1067048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " ivec4 test2;\n" 1067148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1067248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " function(test);\n" 1067348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1067448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " if (test.x > 2)\n" 1067548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " {\n" 1067648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " gl_Position = vec4(1);\n" 1067748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " }\n" 1067848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " else\n" 1067948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " {\n" 1068048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " function2(test2);\n" 1068148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1068248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " gl_Position = vec4(float(test2.x) );\n" 1068348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " }\n" 1068448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n"; 1068548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1068648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.shaderSource(m_vs_id, 1 /* count */, &vs_body, DE_NULL /* length */); 1068748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed"); 1068848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1068948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.compileShader(m_vs_id); 1069048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader() call failed"); 1069148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1069248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getShaderiv(m_vs_id, GL_COMPILE_STATUS, &compile_status); 1069348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv() call failed"); 1069448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1069548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (compile_status == GL_FALSE) 1069648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1069748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos TCU_FAIL("Shader compilation failed"); 1069848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1069948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1070048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Set up & link the test program object */ 1070148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glw::GLint link_status = GL_FALSE; 1070248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1070348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.attachShader(m_po_id, m_vs_id); 1070448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader() call failed."); 1070548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1070648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.linkProgram(m_po_id); 1070748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glLinkProgram() call failed."); 1070848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1070948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getProgramiv(m_po_id, GL_LINK_STATUS, &link_status); 1071048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv() call failed."); 1071148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1071248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (link_status == GL_FALSE) 1071348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1071448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos TCU_FAIL("Program linking failed"); 1071548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1071648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1071748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Query test program object's properties */ 1071848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getProgramStageiv(m_po_id, GL_VERTEX_SHADER, GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS, 1071948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos &m_po_active_subroutine_uniform_locations); 1072048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getProgramStageiv(m_po_id, GL_VERTEX_SHADER, GL_ACTIVE_SUBROUTINE_UNIFORMS, &m_po_active_subroutine_uniforms); 1072148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getProgramStageiv(m_po_id, GL_VERTEX_SHADER, GL_ACTIVE_SUBROUTINES, &m_po_active_subroutines); 1072248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramStageiv() call(s) failed."); 1072348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1072448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_po_active_subroutine_uniform_locations != 2) 1072548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1072648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos TCU_FAIL("Invalid GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS value returned"); 1072748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1072848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1072948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_po_subroutine_test1_index = gl.getSubroutineIndex(m_po_id, GL_VERTEX_SHADER, "test1"); 1073048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_po_subroutine_test2_index = gl.getSubroutineIndex(m_po_id, GL_VERTEX_SHADER, "test2"); 1073148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_po_subroutine_test3_index = gl.getSubroutineIndex(m_po_id, GL_VERTEX_SHADER, "test3"); 1073248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glGetSubroutineIndex() call(s) failed."); 1073348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1073448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_po_subroutine_test1_index == GL_INVALID_INDEX || m_po_subroutine_test2_index == GL_INVALID_INDEX || 1073548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_po_subroutine_test3_index == GL_INVALID_INDEX) 1073648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1073748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos TCU_FAIL("Invalid subroutine index returned"); 1073848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1073948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1074048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_po_subroutine_uniform_function_index = gl.getSubroutineUniformLocation(m_po_id, GL_VERTEX_SHADER, "function"); 1074148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_po_subroutine_uniform_function2_index = gl.getSubroutineUniformLocation(m_po_id, GL_VERTEX_SHADER, "function2"); 1074248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glGetSubroutineUniformLocation() call(s) failed."); 1074348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1074448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_po_subroutine_uniform_function_index == -1 || m_po_subroutine_uniform_function2_index == -1) 1074548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1074648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos TCU_FAIL("Invalid subroutine uniform index returned"); 1074748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1074848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 1074948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1075048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Executes test iteration. 1075148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1075248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed. 1075348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos */ 1075448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulostcu::TestNode::IterateResult NegativeTest1::iterate() 1075548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 1075648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glw::GLenum error_code = GL_NO_ERROR; 1075748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1075848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1075948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Do not execute the test if GL_ARB_shader_subroutine is not supported */ 1076048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_shader_subroutine")) 1076148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1076248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos throw tcu::NotSupportedError("GL_ARB_shader_subroutine is not supported."); 1076348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1076448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1076548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Initialize GL objects required to run the test */ 1076648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos initTest(); 1076748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1076848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* The error INVALID_OPERATION is generated by GetSubroutineUniformLocation 1076948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * if the program object identified by <program> has not been successfully 1077048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * linked. 1077148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos */ 1077248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getSubroutineUniformLocation(m_po_not_linked_id, GL_FRAGMENT_SHADER, "subroutine_uniform_name"); 1077348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1077448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos error_code = gl.getError(); 1077548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1077648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (error_code != GL_INVALID_OPERATION) 1077748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1077848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.getLog() << tcu::TestLog::Message 1077948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << "glGetSubroutineUniformLocation() does not generate GL_INVALID_OPERATION " 1078048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "error code when called for a non-linked program object." 1078148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << tcu::TestLog::EndMessage; 1078248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1078348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_has_test_passed = false; 1078448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1078548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1078648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* The error INVALID_VALUE is generated by GetActiveSubroutineUniformiv or 1078748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * GetActiveSubroutineUniformName if <index> is greater than or equal to the 1078848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * value of ACTIVE_SUBROUTINE_UNIFORMS for the shader stage. 1078948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos */ 1079048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glw::GLint temp_length = 0; 1079148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glw::GLint temp_values = 0; 1079248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1079348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getActiveSubroutineUniformiv(m_po_id, GL_VERTEX_SHADER, m_po_active_subroutine_uniforms, 1079448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GL_NUM_COMPATIBLE_SUBROUTINES, &temp_values); 1079548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos error_code = gl.getError(); 1079648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1079748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (error_code == GL_INVALID_VALUE) 1079848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1079948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getActiveSubroutineUniformiv(m_po_id, GL_VERTEX_SHADER, m_po_active_subroutine_uniforms + 1, 1080048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GL_NUM_COMPATIBLE_SUBROUTINES, &temp_values); 1080148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1080248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos error_code = gl.getError(); 1080348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1080448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1080548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (error_code != GL_INVALID_VALUE) 1080648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1080748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.getLog() << tcu::TestLog::Message 1080848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << "glGetActiveSubroutineUniformiv() does not generate GL_INVALID_VALUE " 1080948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "when passed <index> argument that is greater than or equal to " 1081048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "the value of GL_ACTIVE_SUBROUTINE_UNIFORMS." 1081148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << tcu::TestLog::EndMessage; 1081248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1081348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_has_test_passed = false; 1081448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1081548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1081648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getActiveSubroutineUniformName(m_po_id, GL_VERTEX_SHADER, m_po_active_subroutine_uniforms, 0, /* bufsize */ 1081748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos &temp_length, DE_NULL); /* name */ 1081848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos error_code = gl.getError(); 1081948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1082048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (error_code == GL_INVALID_VALUE) 1082148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1082248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getActiveSubroutineUniformName(m_po_id, GL_VERTEX_SHADER, m_po_active_subroutine_uniforms + 1, 1082348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 0, /* bufsize */ 1082448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos &temp_length, DE_NULL); /* name */ 1082548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1082648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos error_code = gl.getError(); 1082748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1082848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1082948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (error_code != GL_INVALID_VALUE) 1083048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1083148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.getLog() << tcu::TestLog::Message 1083248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << "glGetActiveSubroutineUniformName() does not generate GL_INVALID_VALUE " 1083348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "when passed <index> argument that is greater than or equal to " 1083448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "the value of GL_ACTIVE_SUBROUTINE_UNIFORMS." 1083548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << tcu::TestLog::EndMessage; 1083648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1083748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_has_test_passed = false; 1083848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1083948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1084048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* The error INVALID_VALUE is generated by GetActiveSubroutineName if <index> 1084148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * is greater than or equal to the value of ACTIVE_SUBROUTINES for the shader 1084248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * stage. 1084348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos */ 1084448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getActiveSubroutineName(m_po_id, GL_VERTEX_SHADER, m_po_active_subroutines, 0, /* bufsize */ 1084548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos &temp_length, DE_NULL); /* name */ 1084648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos error_code = gl.getError(); 1084748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1084848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (error_code == GL_INVALID_VALUE) 1084948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1085048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getActiveSubroutineName(m_po_id, GL_VERTEX_SHADER, m_po_active_subroutines + 1, 0, /* bufsize */ 1085148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos &temp_length, DE_NULL); /* name */ 1085248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1085348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos error_code = gl.getError(); 1085448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1085548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1085648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (error_code != GL_INVALID_VALUE) 1085748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1085848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.getLog() << tcu::TestLog::Message << "glGetActiveSubroutineName() does not generate GL_INVALID_VALUE " 1085948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "when passed <index> argument that is greater than or equal to " 1086048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "the value of GL_ACTIVE_SUBROUTINES." 1086148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << tcu::TestLog::EndMessage; 1086248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1086348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_has_test_passed = false; 1086448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1086548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1086648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* The error INVALID_VALUE is generated by UniformSubroutinesuiv if <count> 1086748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * is not equal to the value of ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS for the 1086848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * shader stage <shadertype>. 1086948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos */ 1087048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glw::GLuint index = 0; 1087148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1087248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.useProgram(m_po_id); 1087348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed."); 1087448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1087548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.uniformSubroutinesuiv(GL_VERTEX_SHADER, m_po_active_subroutine_uniform_locations - 1, &index); 1087648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos error_code = gl.getError(); 1087748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1087848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (error_code == GL_INVALID_VALUE) 1087948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1088048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.uniformSubroutinesuiv(GL_VERTEX_SHADER, m_po_active_subroutine_uniform_locations + 1, &index); 1088148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1088248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos error_code = gl.getError(); 1088348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1088448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1088548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (error_code != GL_INVALID_VALUE) 1088648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1088748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.getLog() << tcu::TestLog::Message << "glUniformSubroutinesiv() does not generate GL_INVALID_VALUE " 1088848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "when passed <count> argument that is not equal to the value of " 1088948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS." 1089048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << tcu::TestLog::EndMessage; 1089148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1089248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_has_test_passed = false; 1089348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1089448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1089548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* The error INVALID_VALUE is generated by UniformSubroutinesuiv if any value 1089648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * in <indices> is greater than or equal to the value of ACTIVE_SUBROUTINES 1089748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * for the shader stage. 1089848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos */ 1089948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glw::GLuint invalid_subroutine_indices[4] = { (GLuint)m_po_active_subroutines, (GLuint)m_po_active_subroutines, 1090048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos (GLuint)m_po_active_subroutines + 1, 1090148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos (GLuint)m_po_active_subroutines + 1 }; 1090248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1090348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.uniformSubroutinesuiv(GL_VERTEX_SHADER, m_po_active_subroutine_uniform_locations, /* count */ 1090448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos invalid_subroutine_indices + 0); 1090548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos error_code = gl.getError(); 1090648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1090748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (error_code == GL_INVALID_VALUE) 1090848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1090948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.uniformSubroutinesuiv(GL_VERTEX_SHADER, m_po_active_subroutine_uniform_locations, 1091048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos invalid_subroutine_indices + 2); 1091148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1091248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos error_code = gl.getError(); 1091348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1091448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1091548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (error_code != GL_INVALID_VALUE) 1091648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1091748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.getLog() << tcu::TestLog::Message << "glUniformSubroutinesuiv() does not generate GL_INVALID_VALUE " 1091848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "when the value passed via <indices> argument is greater than " 1091948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "or equal to the value of GL_ACTIVE_SUBROUTINES." 1092048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << tcu::TestLog::EndMessage; 1092148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1092248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_has_test_passed = false; 1092348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1092448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1092548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* The error INVALID_OPERATION is generated by UniformSubroutinesuiv() if any 1092648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * subroutine index in <indices> identifies a subroutine not associated with 1092748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * the type of the subroutine uniform variable assigned to the corresponding 1092848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * location. 1092948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos */ 1093048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glw::GLuint invalid_subroutine_indices2[2] = { m_po_subroutine_test1_index, m_po_subroutine_test1_index }; 1093148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1093248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.uniformSubroutinesuiv(GL_VERTEX_SHADER, m_po_active_subroutine_uniform_locations, invalid_subroutine_indices2); 1093348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos error_code = gl.getError(); 1093448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1093548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (error_code != GL_INVALID_OPERATION) 1093648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1093748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.getLog() << tcu::TestLog::Message 1093848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << "glUniformSubroutinesuiv() does not generate GL_INVALID_OPERATION " 1093948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "when the subroutine index passed via <indices> argument identifies" 1094048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "a subroutine not associated with the type of the subroutine uniform " 1094148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "assigned to the corresponding location." 1094248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << tcu::TestLog::EndMessage; 1094348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1094448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_has_test_passed = false; 1094548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1094648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1094748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* The error INVALID_OPERATION is generated by UniformSubroutinesuiv if no 1094848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * program is active. 1094948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos */ 1095048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glw::GLuint valid_subroutine_locations[2] = { 0 }; 1095148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1095248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos valid_subroutine_locations[m_po_subroutine_uniform_function_index] = m_po_subroutine_test1_index; 1095348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos valid_subroutine_locations[m_po_subroutine_uniform_function2_index] = m_po_subroutine_test3_index; 1095448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1095548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.useProgram(0); 1095648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed."); 1095748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1095848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.uniformSubroutinesuiv(GL_VERTEX_SHADER, m_po_active_subroutine_uniform_locations, valid_subroutine_locations); 1095948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos error_code = gl.getError(); 1096048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1096148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (error_code != GL_INVALID_OPERATION) 1096248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1096348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.getLog() << tcu::TestLog::Message 1096448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << "glUniformSubroutinesuiv() does not generate GL_INVALID_OPERATION " 1096548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "when called without an active program object." 1096648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << tcu::TestLog::EndMessage; 1096748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1096848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_has_test_passed = false; 1096948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1097048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1097148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* The error INVALID_VALUE is generated by GetUniformSubroutineuiv if 1097248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * <location> is greater than or equal to the value of 1097348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS for the shader stage. 1097448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos */ 1097548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glw::GLuint temp_value = 0; 1097648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1097748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.useProgram(m_po_id); 1097848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed."); 1097948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1098048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getUniformSubroutineuiv(GL_VERTEX_SHADER, m_po_active_subroutine_uniform_locations, &temp_value); 1098148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos error_code = gl.getError(); 1098248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1098348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (error_code == GL_INVALID_VALUE) 1098448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1098548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getUniformSubroutineuiv(GL_VERTEX_SHADER, m_po_active_subroutine_uniform_locations + 1, &temp_value); 1098648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos error_code = gl.getError(); 1098748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1098848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1098948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (error_code != GL_INVALID_VALUE) 1099048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1099148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.getLog() << tcu::TestLog::Message 1099248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << "glGetUniformSubroutineuiv() does not generate GL_INVALID_VALUE " 1099348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "when called for location that is greater than or equal to the value " 1099448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "of GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS." 1099548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << tcu::TestLog::EndMessage; 1099648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1099748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_has_test_passed = false; 1099848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1099948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1100048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* The error INVALID_OPERATION is generated by GetUniformSubroutineuiv if no 1100148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * program is active for the shader stage identified by <shadertype>. 1100248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos */ 1100348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::GLenum undefined_shader_stages[] = { GL_FRAGMENT_SHADER, GL_GEOMETRY_SHADER, GL_TESS_CONTROL_SHADER, 1100448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GL_TESS_EVALUATION_SHADER }; 1100548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const unsigned int n_undefined_shader_stages = sizeof(undefined_shader_stages) / sizeof(undefined_shader_stages[0]); 1100648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1100748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (unsigned int n_undefined_shader_stage = 0; n_undefined_shader_stage < n_undefined_shader_stages; 1100848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos ++n_undefined_shader_stage) 1100948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1101048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glw::GLenum shader_stage = undefined_shader_stages[n_undefined_shader_stage]; 1101148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1101248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getUniformSubroutineuiv(shader_stage, 0, /* location */ 1101348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos &temp_value); 1101448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos error_code = gl.getError(); 1101548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1101648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (error_code != GL_INVALID_OPERATION) 1101748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1101848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.getLog() << tcu::TestLog::Message 1101948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << "glGetUniformSubroutineuiv() does not generate GL_INVALID_OPERATION " 1102048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "when called for a shader stage that is not defined for active " 1102148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "program object." 1102248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << tcu::TestLog::EndMessage; 1102348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1102448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_has_test_passed = false; 1102548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1102648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } /* for (all undefined shader stages) */ 1102748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1102848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* All done */ 1102948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_has_test_passed) 1103048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1103148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 1103248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1103348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else 1103448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1103548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 1103648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1103748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1103848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return STOP; 1103948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 1104048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1104148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Constructor 1104248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1104348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param context Rendering context. 1104448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1104548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 1104648087f5f0eb08759ee763f98daf3b34becb74559Pyry HaulosNegativeTest2::NegativeTest2(deqp::Context& context) 1104748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos : TestCase(context, "subroutine_uniform_scope", "Verifies subroutine uniforms declared in shader stage A" 1104848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "cannot be accessed from a different stage.") 1104948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_fs_id(0) 1105048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_gs_id(0) 1105148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_has_test_passed(true) 1105248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_po_id(0) 1105348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_tc_id(0) 1105448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_te_id(0) 1105548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_vs_id(0) 1105648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 1105748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Left blank intentionally */ 1105848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 1105948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1106048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Deinitializes all GL objects that may have been created during test execution */ 1106148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid NegativeTest2::deinit() 1106248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 1106348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos deinitGLObjects(); 1106448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 1106548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1106648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Deinitializes all GL objects that may have been created during test execution */ 1106748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid NegativeTest2::deinitGLObjects() 1106848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 1106948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1107048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1107148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_fs_id != 0) 1107248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1107348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteShader(m_fs_id); 1107448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1107548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_fs_id = 0; 1107648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1107748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1107848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_gs_id != 0) 1107948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1108048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteShader(m_gs_id); 1108148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1108248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_gs_id = 0; 1108348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1108448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1108548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_tc_id != 0) 1108648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1108748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteShader(m_tc_id); 1108848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1108948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_tc_id = 0; 1109048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1109148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1109248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_te_id != 0) 1109348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1109448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteShader(m_te_id); 1109548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1109648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_te_id = 0; 1109748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1109848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1109948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_vs_id != 0) 1110048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1110148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteShader(m_vs_id); 1110248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1110348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_vs_id = 0; 1110448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1110548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1110648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_po_id != 0) 1110748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1110848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteProgram(m_po_id); 1110948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1111048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_po_id = 0; 1111148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1111248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 1111348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1111448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Builds an offending program object and tries to link it. We're either expecting 1111548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * a compile-time or link-time error here. 1111648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1111748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * If the program object builds successfully, the test has failed. 1111848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1111948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param referencing_stage Shader stage which defines a subroutine uniform that 1112048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * should be called from fragment/geometry/tess control/ 1112148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * tess evaluation/vertex shader stages. 1112248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1112348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 1112448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid NegativeTest2::executeTestCase(const Utils::_shader_stage& referencing_stage) 1112548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 1112648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1112748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1112848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const std::string fs_body = getFragmentShaderBody(referencing_stage); 1112948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const std::string gs_body = getGeometryShaderBody(referencing_stage); 1113048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const std::string tc_body = getTessellationControlShaderBody(referencing_stage); 1113148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const std::string te_body = getTessellationEvaluationShaderBody(referencing_stage); 1113248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const std::string vs_body = getVertexShaderBody(referencing_stage); 1113348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1113448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (Utils::buildProgram(gl, vs_body, tc_body, te_body, gs_body, fs_body, NULL, /* xfb_varyings */ 1113548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 0, /* n_xfb_varyings */ 1113648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos &m_vs_id, &m_tc_id, &m_te_id, &m_gs_id, &m_fs_id, &m_po_id)) 1113748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1113848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Test program should not have built correctly ! */ 1113948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.getLog() << tcu::TestLog::Message << "In the following program, one of the stages references " 1114048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "a subroutine that is defined in another stage. This " 1114148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "is forbidden by the specification.\n" 1114248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1114348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "Vertex shader:\n\n" 1114448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << vs_body.c_str() << "\n\nTessellation control shader:\n\n" 1114548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << tc_body.c_str() << "\n\nTessellation evaluation shader:\n\n" 1114648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << te_body.c_str() << "\n\nGeometry shader:\n\n" 1114748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << gs_body.c_str() << "\n\nFragment shader:\n\n" 1114848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << fs_body.c_str() << tcu::TestLog::EndMessage; 1114948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1115048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_has_test_passed = false; 1115148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } /* if (test program was built successfully) */ 1115248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1115348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Release the shaders & the program object that buildProgram() created */ 1115448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos deinitGLObjects(); 1115548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 1115648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1115748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Retrieves an offending fragment shader body. 1115848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1115948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param referencing_stage Shader stage which defines the subroutine uniform that 1116048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * will be called from fragment shader. 1116148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1116248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return Requested string. 1116348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 1116448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosstd::string NegativeTest2::getFragmentShaderBody(const Utils::_shader_stage& referencing_stage) const 1116548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 1116648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::stringstream result; 1116748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1116848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Form the pre-amble */ 1116948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result << "#version 400\n" 1117048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1117148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "#extension GL_ARB_shader_subroutine : require\n" 1117248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1117348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine void testSubroutineType(out vec4 test_argument);\n" 1117448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1117548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Define a subroutine */ 1117648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine(testSubroutineType) void fs_subroutine(out vec4 test_argument)\n" 1117748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 1117848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " test_argument = vec4(1, 0, 0, 0);\n" 1117948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 1118048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1118148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Define output variables */ 1118248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "out vec4 result;\n" 1118348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1118448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Define uniforms */ 1118548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine uniform testSubroutineType test_fs_subroutine;\n" 1118648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1118748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Define main() */ 1118848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void main()\n" 1118948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 1119048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " " 1119148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << getSubroutineUniformName(referencing_stage) << "(result);\n" 1119248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n"; 1119348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1119448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return result.str(); 1119548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 1119648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1119748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Retrieves an offending geometry shader body. 1119848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1119948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param referencing_stage Shader stage which defines the subroutine uniform that 1120048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * will be called from geometry shader. 1120148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1120248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return Requested string. 1120348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 1120448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosstd::string NegativeTest2::getGeometryShaderBody(const Utils::_shader_stage& referencing_stage) const 1120548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 1120648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::stringstream result; 1120748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1120848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Form the pre-amble */ 1120948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result << "#version 400\n" 1121048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1121148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "#extension GL_ARB_shader_subroutine : require\n" 1121248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1121348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine void testSubroutineType(out vec4 test_argument);\n" 1121448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1121548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "layout(points) in;\n" 1121648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "layout(points, max_vertices = 1) out;\n" 1121748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1121848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Define a subroutine */ 1121948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine(testSubroutineType) void gs_subroutine(out vec4 test_argument)\n" 1122048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 1122148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " test_argument = vec4(0, 1, 1, 1);\n" 1122248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 1122348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1122448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Define output variables */ 1122548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "out vec4 result;\n" 1122648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1122748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Define uniforms */ 1122848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine uniform testSubroutineType test_gs_subroutine;\n" 1122948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1123048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Define main() */ 1123148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void main()\n" 1123248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 1123348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " " 1123448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << getSubroutineUniformName(referencing_stage) << "(result);\n" 1123548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n"; 1123648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1123748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return result.str(); 1123848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 1123948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1124048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Retrieves name of the subroutine uniform that is defined in user-specified 1124148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * shader stage. 1124248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1124348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param stage Shader stage to retrieve the subroutine uniform name for. 1124448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1124548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return As per description. 1124648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 1124748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosstd::string NegativeTest2::getSubroutineUniformName(const Utils::_shader_stage& stage) const 1124848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 1124948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::string result = "?"; 1125048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1125148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos switch (stage) 1125248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1125348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case Utils::SHADER_STAGE_FRAGMENT: 1125448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1125548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = "test_fs_subroutine"; 1125648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1125748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 1125848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1125948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1126048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case Utils::SHADER_STAGE_GEOMETRY: 1126148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1126248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = "test_gs_subroutine"; 1126348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1126448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 1126548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1126648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1126748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case Utils::SHADER_STAGE_TESSELLATION_CONTROL: 1126848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1126948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = "test_tc_subroutine"; 1127048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1127148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 1127248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1127348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1127448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case Utils::SHADER_STAGE_TESSELLATION_EVALUATION: 1127548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1127648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = "test_te_subroutine"; 1127748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1127848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 1127948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1128048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1128148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case Utils::SHADER_STAGE_VERTEX: 1128248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1128348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = "test_vs_subroutine"; 1128448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1128548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 1128648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1128748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1128848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos default: 1128948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1129048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos TCU_FAIL("Unrecognized shader stage requested"); 1129148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1129248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } /* switch (stage) */ 1129348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1129448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return result; 1129548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 1129648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1129748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Retrieves an offending tessellation control shader body. 1129848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1129948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param referencing_stage Shader stage which defines the subroutine uniform that 1130048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * will be called from tessellation control shader. 1130148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1130248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return Requested string. 1130348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 1130448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosstd::string NegativeTest2::getTessellationControlShaderBody(const Utils::_shader_stage& referencing_stage) const 1130548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 1130648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::stringstream result; 1130748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1130848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Form the pre-amble */ 1130948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result << "#version 400\n" 1131048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1131148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "#extension GL_ARB_shader_subroutine : require\n" 1131248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1131348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "layout(vertices = 4) out;\n" 1131448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1131548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine void testSubroutineType(out vec4 test_argument);\n" 1131648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1131748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Define a subroutine */ 1131848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine(testSubroutineType) void tc_subroutine(out vec4 test_argument)\n" 1131948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 1132048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " test_argument = vec4(0, 0, 1, 0);\n" 1132148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 1132248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1132348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Define uniforms */ 1132448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine uniform testSubroutineType test_tc_subroutine;\n" 1132548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1132648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Define main() */ 1132748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void main()\n" 1132848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 1132948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " " 1133048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << getSubroutineUniformName(referencing_stage) << "(gl_out[gl_InvocationID].gl_Position);\n" 1133148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n"; 1133248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1133348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return result.str(); 1133448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 1133548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1133648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Retrieves an offending tessellation evaluation shader body. 1133748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1133848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param referencing_stage Shader stage which defines the subroutine uniform that 1133948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * will be called from tessellation evaluation shader. 1134048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1134148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return Requested string. 1134248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 1134348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosstd::string NegativeTest2::getTessellationEvaluationShaderBody(const Utils::_shader_stage& referencing_stage) const 1134448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 1134548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::stringstream result; 1134648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1134748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Form the pre-amble */ 1134848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result << "#version 400\n" 1134948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1135048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "#extension GL_ARB_shader_subroutine : require\n" 1135148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1135248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "layout(quads) in;\n" 1135348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1135448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine void testSubroutineType(out vec4 test_argument);\n" 1135548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1135648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Define a subroutine */ 1135748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine(testSubroutineType) void te_subroutine(out vec4 test_argument)\n" 1135848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 1135948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " test_argument = vec4(1, 1, 1, 1);\n" 1136048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 1136148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1136248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Define uniforms */ 1136348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine uniform testSubroutineType test_te_subroutine;\n" 1136448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1136548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Define main() */ 1136648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void main()\n" 1136748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 1136848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " " 1136948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << getSubroutineUniformName(referencing_stage) << "(gl_Position);\n" 1137048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n"; 1137148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1137248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return result.str(); 1137348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 1137448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1137548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Retrieves an offending vertex shader body. 1137648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1137748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param referencing_stage Shader stage which defines the subroutine uniform that 1137848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * will be called from vertex shader. 1137948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1138048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return Requested string. 1138148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 1138248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosstd::string NegativeTest2::getVertexShaderBody(const Utils::_shader_stage& referencing_stage) const 1138348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 1138448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::stringstream result; 1138548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1138648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Form the pre-amble */ 1138748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result << "#version 400\n" 1138848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1138948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "#extension GL_ARB_shader_subroutine : require\n" 1139048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1139148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine void testSubroutineType(out vec4 test_argument);\n" 1139248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1139348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Define a subroutine */ 1139448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine(testSubroutineType) void vs_subroutine(out vec4 test_argument)\n" 1139548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 1139648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " test_argument = vec4(0, 1, 0, 0);\n" 1139748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 1139848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1139948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Define uniforms */ 1140048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine uniform testSubroutineType test_vs_subroutine;\n" 1140148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1140248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Define main() */ 1140348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void main()\n" 1140448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 1140548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " " 1140648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << getSubroutineUniformName(referencing_stage) << "(gl_Position);\n" 1140748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n"; 1140848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1140948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return result.str(); 1141048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 1141148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1141248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Executes test iteration. 1141348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1141448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed. 1141548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos */ 1141648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulostcu::TestNode::IterateResult NegativeTest2::iterate() 1141748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 1141848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Do not execute the test if GL_ARB_shader_subroutine is not supported */ 1141948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_shader_subroutine")) 1142048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1142148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos throw tcu::NotSupportedError("GL_ARB_shader_subroutine is not supported."); 1142248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1142348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1142448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Iterate over all shader stages and execute the checks */ 1142548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (int referencing_stage = static_cast<int>(Utils::SHADER_STAGE_FIRST); 1142648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos referencing_stage < static_cast<int>(Utils::SHADER_STAGE_COUNT); ++referencing_stage) 1142748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1142848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos executeTestCase(static_cast<Utils::_shader_stage>(referencing_stage)); 1142948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } /* for (all test cases) */ 1143048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1143148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* All done */ 1143248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_has_test_passed) 1143348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1143448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 1143548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1143648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else 1143748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1143848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 1143948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1144048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1144148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return STOP; 1144248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 1144348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1144448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Constructor. 1144548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1144648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param context Rendering context. 1144748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1144848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 1144948087f5f0eb08759ee763f98daf3b34becb74559Pyry HaulosNegativeTest3::NegativeTest3(deqp::Context& context) 1145048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos : TestCase(context, "missing_subroutine_keyword", "Verifies that subroutine keyword is necessary when declaring a " 1145148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine uniforn and a compilation error occurs without it.") 1145248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_has_test_passed(true) 1145348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_so_id(0) 1145448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 1145548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Left blank intentionally */ 1145648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 1145748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1145848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Deinitializes all GL objects that may have been created during test execution */ 1145948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid NegativeTest3::deinit() 1146048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 1146148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1146248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1146348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_so_id != 0) 1146448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1146548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteShader(m_so_id); 1146648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1146748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_so_id = 0; 1146848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1146948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 1147048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1147148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Verifies that broken shader (for user-specified shader stage) does not compile. 1147248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1147348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param shader_stage Shader stage to use for the test. 1147448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 1147548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid NegativeTest3::executeTest(const Utils::_shader_stage& shader_stage) 1147648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 1147748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1147848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1147948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Generate a new shader object */ 1148048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_so_id = gl.createShader(Utils::getGLenumForShaderStage(shader_stage)); 1148148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call failed."); 1148248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1148348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Assign body to the shader */ 1148448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::string body; 1148548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* body_raw_ptr = DE_NULL; 1148648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1148748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos switch (shader_stage) 1148848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1148948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case Utils::SHADER_STAGE_VERTEX: 1149048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos body = getVertexShaderBody(); 1149148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 1149248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case Utils::SHADER_STAGE_TESSELLATION_CONTROL: 1149348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos body = getTessellationControlShaderBody(); 1149448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 1149548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case Utils::SHADER_STAGE_TESSELLATION_EVALUATION: 1149648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos body = getTessellationEvaluationShaderBody(); 1149748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 1149848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case Utils::SHADER_STAGE_GEOMETRY: 1149948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos body = getGeometryShaderBody(); 1150048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 1150148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case Utils::SHADER_STAGE_FRAGMENT: 1150248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos body = getFragmentShaderBody(); 1150348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 1150448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1150548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos default: 1150648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1150748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos TCU_FAIL("Unrecognized shader stage requested"); 1150848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1150948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } /* switch (shader_stage) */ 1151048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1151148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos body_raw_ptr = body.c_str(); 1151248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1151348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.shaderSource(m_so_id, 1 /* count */, &body_raw_ptr, DE_NULL /* length */); 1151448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed."); 1151548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1151648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Try to compile the shader */ 1151748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glw::GLint compile_status = 0; 1151848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1151948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.compileShader(m_so_id); 1152048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader() call failed."); 1152148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1152248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getShaderiv(m_so_id, GL_COMPILE_STATUS, &compile_status); 1152348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv() call failed."); 1152448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1152548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (compile_status == GL_TRUE) 1152648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1152748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.getLog() << tcu::TestLog::Message << "The following shader was expected to fail to compile but was " 1152848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "accepted by the compiler:\n" 1152948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1153048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << body.c_str() << tcu::TestLog::EndMessage; 1153148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1153248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_has_test_passed = false; 1153348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1153448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1153548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Good to release the shader at this point */ 1153648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteShader(m_so_id); 1153748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteShader() call failed."); 1153848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 1153948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1154048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Retrieves body of a broken fragment shader. 1154148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1154248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return Requested string. 1154348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 1154448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosstd::string NegativeTest3::getFragmentShaderBody() const 1154548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 1154648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return "#version 400\n" 1154748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1154848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "#extension GL_ARB_shader_subroutine : require\n" 1154948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1155048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine void testSubroutineType(inout vec4 test);\n" 1155148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1155248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void testSubroutine1(inout vec4 test)\n" 1155348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 1155448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " test += vec4(3, 4, 5, 6);\n" 1155548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 1155648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1155748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "uniform testSubroutineType subroutineFunction;\n" 1155848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "out vec4 result;\n" 1155948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1156048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void main()\n" 1156148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 1156248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " vec4 test = vec4(2, 3, 4, 5);\n" 1156348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1156448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " subroutineFunction(test);\n" 1156548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1156648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " result = test;\n" 1156748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n"; 1156848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 1156948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1157048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Retrieves body of a broken geometry shader. 1157148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1157248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return Requested string. 1157348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 1157448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosstd::string NegativeTest3::getGeometryShaderBody() const 1157548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 1157648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return "#version 400\n" 1157748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1157848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "#extension GL_ARB_shader_subroutine : require\n" 1157948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1158048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "layout(points) in;\n" 1158148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "layout(points, max_vertices = 1) out;\n" 1158248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1158348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine void testSubroutineType(inout vec4 test);\n" 1158448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1158548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void testSubroutine1(inout vec4 test)\n" 1158648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 1158748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " test += vec4(3, 4, 5, 6);\n" 1158848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 1158948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1159048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "uniform testSubroutineType subroutineFunction;\n" 1159148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1159248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void main()\n" 1159348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 1159448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " vec4 test = vec4(2, 3, 4, 5);\n" 1159548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1159648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " subroutineFunction(test);\n" 1159748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1159848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " gl_Position = test;\n" 1159948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " EmitVertex();\n" 1160048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n"; 1160148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 1160248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1160348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Retrieves body of a broken tessellation control shader. 1160448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1160548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return Requested string. 1160648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 1160748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosstd::string NegativeTest3::getTessellationControlShaderBody() const 1160848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 1160948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return "#version 400\n" 1161048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1161148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "#extension GL_ARB_shader_subroutine : require\n" 1161248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1161348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "layout(vertices=4) out;\n" 1161448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1161548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine void testSubroutineType(inout vec4 test);\n" 1161648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1161748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void testSubroutine1(inout vec4 test)\n" 1161848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 1161948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " test += vec4(1, 2, 3, 4);\n" 1162048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 1162148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1162248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "uniform testSubroutineType subroutineFunction;\n" 1162348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1162448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void main()\n" 1162548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 1162648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " vec4 test = vec4(0, 1, 2, 3);\n" 1162748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1162848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " subroutineFunction(test);\n" 1162948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1163048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " gl_out[gl_InvocationID].gl_Position = test;\n" 1163148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n"; 1163248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 1163348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1163448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Retrieves body of a broken tessellation evaluation shader. 1163548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1163648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return Requested string. 1163748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 1163848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosstd::string NegativeTest3::getTessellationEvaluationShaderBody() const 1163948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 1164048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return "#version 400\n" 1164148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1164248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "#extension GL_ARB_shader_subroutine : require\n" 1164348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1164448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "layout(quads) in;\n" 1164548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1164648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine void testSubroutineType(inout vec4 test);\n" 1164748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1164848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void testSubroutine1(inout vec4 test)\n" 1164948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 1165048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " test += vec4(2, 3, 4, 5);\n" 1165148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 1165248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1165348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "uniform testSubroutineType subroutineFunction;\n" 1165448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1165548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void main()\n" 1165648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 1165748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " vec4 test = vec4(1, 2, 3, 4);\n" 1165848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1165948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " subroutineFunction(test);\n" 1166048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1166148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " gl_Position = test;\n" 1166248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n"; 1166348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 1166448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1166548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Retrieves body of a broken vertex shader. 1166648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1166748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return Requested string. 1166848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 1166948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosstd::string NegativeTest3::getVertexShaderBody() const 1167048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 1167148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return "#version 400\n" 1167248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1167348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "#extension GL_ARB_shader_subroutine : require\n" 1167448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1167548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine void testSubroutineType(inout vec4 test);\n" 1167648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1167748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void testSubroutine1(inout vec4 test)\n" 1167848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 1167948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " test += vec4(0, 1, 2, 3);\n" 1168048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 1168148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1168248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "uniform testSubroutineType subroutineFunction;\n" 1168348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1168448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void main()\n" 1168548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 1168648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " subroutineFunction(gl_Position);\n" 1168748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n"; 1168848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 1168948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1169048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Executes test iteration. 1169148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1169248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed. 1169348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos */ 1169448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulostcu::TestNode::IterateResult NegativeTest3::iterate() 1169548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 1169648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Do not execute the test if GL_ARB_shader_subroutine is not supported */ 1169748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_shader_subroutine")) 1169848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1169948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos throw tcu::NotSupportedError("GL_ARB_shader_subroutine is not supported."); 1170048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1170148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1170248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Iterate over all shader stages */ 1170348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (int shader_stage = static_cast<int>(Utils::SHADER_STAGE_FIRST); 1170448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos shader_stage < static_cast<int>(Utils::SHADER_STAGE_COUNT); ++shader_stage) 1170548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1170648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos executeTest(static_cast<Utils::_shader_stage>(shader_stage)); 1170748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } /* for (all shader stages) */ 1170848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1170948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Done */ 1171048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_has_test_passed) 1171148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1171248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 1171348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1171448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else 1171548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1171648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 1171748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1171848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1171948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return STOP; 1172048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 1172148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1172248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Constructor. 1172348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1172448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param context Rendering context. 1172548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1172648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 1172748087f5f0eb08759ee763f98daf3b34becb74559Pyry HaulosNegativeTest4::NegativeTest4(deqp::Context& context) 1172848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos : TestCase(context, "subroutines_incompatible_with_subroutine_type", 1172948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "Verifies that a compile-time error is generated when arguments and " 1173048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "return type do not match beween the function and each associated " 1173148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine type.") 1173248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_has_test_passed(true) 1173348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_so_id(0) 1173448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 1173548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Left blank intentionally */ 1173648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 1173748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1173848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Deinitializes GL objects that may have been created during test 1173948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * execution. 1174048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 1174148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid NegativeTest4::deinit() 1174248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 1174348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1174448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1174548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_so_id != 0) 1174648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1174748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteShader(m_so_id); 1174848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1174948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_so_id = 0; 1175048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1175148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 1175248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1175348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Retrieves body of a shader of user-specified type that should be used 1175448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * for a single test iteration. The shader will define user-specified number 1175548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * of subroutine types, with the last type either defining an additional argument 1175648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * or using a different return type. 1175748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * A subroutine (claimed compatible with *all* subroutine types) will also be 1175848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * defined in the shader. 1175948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1176048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param shader_stage Shader stage to use for the query. 1176148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param n_subroutine_types Overall number of subroutine types that will be 1176248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * declared & used in the shader. Please see description 1176348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * for more details. 1176448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1176548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return Requested string. 1176648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 1176748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosstd::string NegativeTest4::getShaderBody(const Utils::_shader_stage& shader_stage, 1176848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const unsigned int& n_subroutine_types, const _test_case& test_case) const 1176948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 1177048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::stringstream result_sstream; 1177148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1177248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Form the pre-amble */ 1177348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "#version 400\n" 1177448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1177548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "#extension GL_ARB_shader_subroutine : require\n" 1177648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n"; 1177748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1177848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Inject stage-specific code */ 1177948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos switch (shader_stage) 1178048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1178148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case Utils::SHADER_STAGE_GEOMETRY: 1178248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1178348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "layout (points) in;\n" 1178448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "layout (points, max_vertices = 1) out;\n" 1178548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n"; 1178648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1178748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 1178848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1178948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1179048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case Utils::SHADER_STAGE_TESSELLATION_CONTROL: 1179148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1179248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "layout (vertices = 4) out;\n" 1179348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n"; 1179448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1179548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 1179648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1179748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1179848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case Utils::SHADER_STAGE_TESSELLATION_EVALUATION: 1179948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1180048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "layout (quads) in;\n" 1180148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n"; 1180248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1180348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 1180448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1180548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1180648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos default: 1180748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 1180848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } /* switch (shader_stage) */ 1180948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1181048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Insert subroutine type declarations */ 1181148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (unsigned int n_subroutine_type = 0; n_subroutine_type < n_subroutine_types - 1; ++n_subroutine_type) 1181248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1181348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "subroutine void subroutineType" << n_subroutine_type << "(inout vec3 argument);\n"; 1181448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } /* for (all subroutine types) */ 1181548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1181648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos switch (test_case) 1181748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1181848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case TEST_CASE_INCOMPATIBLE_ARGUMENT_LIST: 1181948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1182048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "subroutine void subroutineType" << (n_subroutine_types - 1) 1182148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << "(inout vec3 argument, out vec4 argument2);\n"; 1182248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1182348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 1182448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1182548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1182648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case TEST_CASE_INCOMPATIBLE_RETURN_TYPE: 1182748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1182848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "subroutine int subroutineType" << (n_subroutine_types - 1) << "(inout vec3 argument);\n"; 1182948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1183048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 1183148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1183248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1183348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos default: 1183448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1183548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos TCU_FAIL("Unrecognized test case"); 1183648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1183748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } /* switch (test_case) */ 1183848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1183948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Insert subroutine declarations */ 1184048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "subroutine("; 1184148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1184248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (unsigned int n_subroutine_type = 0; n_subroutine_type < n_subroutine_types; ++n_subroutine_type) 1184348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1184448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "subroutineType" << n_subroutine_type; 1184548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1184648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (n_subroutine_type != (n_subroutine_types - 1)) 1184748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1184848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << ", "; 1184948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1185048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } /* for (all subroutine types) */ 1185148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1185248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << ") void function(inout vec3 argument)\n" 1185348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 1185448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " argument = vec3(1, 2, 3);\n" 1185548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 1185648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n"; 1185748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1185848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Insert remaining required stage-specific bits */ 1185948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos switch (shader_stage) 1186048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1186148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case Utils::SHADER_STAGE_FRAGMENT: 1186248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1186348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "out vec4 result;\n" 1186448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1186548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void main()\n" 1186648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 1186748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " result = vec4(1, 2, 3, 4);\n" 1186848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n"; 1186948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1187048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 1187148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1187248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1187348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case Utils::SHADER_STAGE_GEOMETRY: 1187448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1187548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "void main()\n" 1187648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 1187748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " gl_Position = vec4(1, 2, 3, 4);\n" 1187848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " EmitVertex();\n" 1187948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n"; 1188048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1188148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 1188248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1188348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1188448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case Utils::SHADER_STAGE_TESSELLATION_CONTROL: 1188548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1188648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "void main()\n" 1188748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 1188848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " gl_TessLevelInner[0] = 1;\n" 1188948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " gl_TessLevelInner[1] = 1;\n" 1189048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " gl_TessLevelOuter[0] = 1;\n" 1189148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " gl_TessLevelOuter[1] = 1;\n" 1189248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " gl_TessLevelOuter[2] = 1;\n" 1189348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " gl_TessLevelOuter[3] = 1;\n" 1189448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " gl_out[gl_InvocationID].gl_Position = vec4(2, 3, 4, 5);\n" 1189548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n"; 1189648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1189748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 1189848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1189948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1190048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case Utils::SHADER_STAGE_TESSELLATION_EVALUATION: 1190148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case Utils::SHADER_STAGE_VERTEX: 1190248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1190348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "void main()\n" 1190448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 1190548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " gl_Position = vec4(1, 2, 3, 4);\n" 1190648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n"; 1190748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1190848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 1190948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1191048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1191148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos default: 1191248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1191348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos TCU_FAIL("Unrecognized shader stage"); 1191448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1191548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } /* switch (shader_stage) */ 1191648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1191748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return result_sstream.str(); 1191848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 1191948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1192048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Executes test iteration. 1192148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1192248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed. 1192348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos */ 1192448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulostcu::TestNode::IterateResult NegativeTest4::iterate() 1192548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 1192648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1192748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1192848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Do not execute the test if GL_ARB_shader_subroutine is not supported */ 1192948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_shader_subroutine")) 1193048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1193148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos throw tcu::NotSupportedError("GL_ARB_shader_subroutine is not supported."); 1193248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1193348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1193448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Iterate over all shader stages.. */ 1193548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (int shader_stage = static_cast<int>(Utils::SHADER_STAGE_FIRST); 1193648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos shader_stage != static_cast<int>(Utils::SHADER_STAGE_COUNT); ++shader_stage) 1193748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1193848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* For each shader stage, we will be trying to compile a number of invalid shaders. 1193948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * Each shader defines N different subroutine types. (N-1) of them are compatible 1194048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * with a subroutine, but exactly 1 will be mismatched. The test passes if GLSL 1194148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * compiler correctly detects that all shaders we will be trying to compile are 1194248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * broken. 1194348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos */ 1194448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::GLenum shader_type = Utils::getGLenumForShaderStage(static_cast<Utils::_shader_stage>(shader_stage)); 1194548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1194648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (unsigned int n_subroutine_types = 1; n_subroutine_types < 6; /* arbitrary number */ 1194748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos ++n_subroutine_types) 1194848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1194948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (int test_case = static_cast<int>(TEST_CASE_FIRST); test_case != static_cast<int>(TEST_CASE_COUNT); 1195048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos ++test_case) 1195148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1195248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::string body; 1195348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* body_raw_ptr = NULL; 1195448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glw::GLint compile_status = GL_FALSE; 1195548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1195648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos body = getShaderBody(static_cast<Utils::_shader_stage>(shader_stage), n_subroutine_types, 1195748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static_cast<_test_case>(test_case)); 1195848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos body_raw_ptr = body.c_str(); 1195948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1196048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Try to compile the shader */ 1196148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_so_id = gl.createShader(shader_type); 1196248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call failed"); 1196348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1196448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.shaderSource(m_so_id, 1 /* count */, &body_raw_ptr, DE_NULL); 1196548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed"); 1196648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1196748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.compileShader(m_so_id); 1196848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader() call failed"); 1196948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1197048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getShaderiv(m_so_id, GL_COMPILE_STATUS, &compile_status); 1197148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv() call failed."); 1197248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1197348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (compile_status == GL_TRUE) 1197448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1197548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.getLog() << tcu::TestLog::Message << "A malformed " 1197648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << Utils::getShaderStageString(static_cast<Utils::_shader_stage>(shader_stage)) 1197748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << " compiled successfully " 1197848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "(" 1197948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << n_subroutine_types << " subroutine types " 1198048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "were defined)." 1198148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << tcu::TestLog::EndMessage; 1198248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1198348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_has_test_passed = false; 1198448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1198548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1198648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Release the object */ 1198748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteShader(m_so_id); 1198848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteShader() call failed."); 1198948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } /* for (all test cases) */ 1199048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } /* for (a number of different subroutine type declarations) */ 1199148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } /* for (all shader stages) */ 1199248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1199348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Done */ 1199448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_has_test_passed) 1199548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1199648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 1199748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1199848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else 1199948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1200048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 1200148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1200248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1200348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return STOP; 1200448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 1200548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1200648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Constructor. 1200748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1200848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param context Rendering context. 1200948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1201048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 1201148087f5f0eb08759ee763f98daf3b34becb74559Pyry HaulosNegativeTest5::NegativeTest5(deqp::Context& context) 1201248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos : TestCase(context, "subroutine_uniform_wo_matching_subroutines", 1201348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "Verifies that a link- or compile-time error occurs when " 1201448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "trying to link a program with no subroutine for subroutine " 1201548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "uniform variable.") 1201648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_fs_id(0) 1201748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_gs_id(0) 1201848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_has_test_passed(true) 1201948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_po_id(0) 1202048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_tc_id(0) 1202148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_te_id(0) 1202248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_vs_id(0) 1202348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 1202448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Left blank intentionally */ 1202548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 1202648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1202748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Deinitializes all GL objects that may have been created during test execution */ 1202848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid NegativeTest5::deinit() 1202948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 1203048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos deinitIteration(); 1203148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 1203248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1203348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Deinitializes all GL objects that may have been created during a single test 1203448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * iteration. 1203548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos ***/ 1203648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid NegativeTest5::deinitIteration() 1203748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 1203848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1203948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1204048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_fs_id != 0) 1204148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1204248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteShader(m_fs_id); 1204348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1204448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_fs_id = 0; 1204548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1204648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1204748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_gs_id != 0) 1204848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1204948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteShader(m_gs_id); 1205048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1205148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_gs_id = 0; 1205248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1205348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1205448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_po_id != 0) 1205548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1205648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteProgram(m_po_id); 1205748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1205848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_po_id = 0; 1205948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1206048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1206148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_tc_id != 0) 1206248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1206348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteShader(m_tc_id); 1206448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1206548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_tc_id = 0; 1206648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1206748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1206848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_te_id != 0) 1206948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1207048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteShader(m_te_id); 1207148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1207248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_te_id = 0; 1207348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1207448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1207548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_vs_id != 0) 1207648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1207748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteShader(m_vs_id); 1207848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1207948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_vs_id = 0; 1208048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1208148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 1208248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1208348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Executes a single test iteration. 1208448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1208548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * If the iteration fails, m_has_test_passed will be set to false. 1208648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1208748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param shader_stage Shader stage, for which a subroutine uniform should be 1208848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * declared in the shader without a matching subroutine. 1208948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 1209048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid NegativeTest5::executeIteration(const Utils::_shader_stage& shader_stage) 1209148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 1209248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::string fs_body = getFragmentShaderBody(shader_stage == Utils::SHADER_STAGE_FRAGMENT); 1209348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::string gs_body = getGeometryShaderBody(shader_stage == Utils::SHADER_STAGE_GEOMETRY); 1209448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::string tc_body = getTessellationControlShaderBody(shader_stage == Utils::SHADER_STAGE_TESSELLATION_CONTROL); 1209548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::string te_body = 1209648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos getTessellationEvaluationShaderBody(shader_stage == Utils::SHADER_STAGE_TESSELLATION_EVALUATION); 1209748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::string vs_body = getVertexShaderBody(shader_stage == Utils::SHADER_STAGE_VERTEX); 1209848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1209948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (Utils::buildProgram(m_context.getRenderContext().getFunctions(), vs_body, tc_body, te_body, gs_body, fs_body, 1210048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos DE_NULL, /* xfb_varyings */ 1210148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos DE_NULL, /* n_xfb_varyings */ 1210248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos &m_vs_id, &m_tc_id, &m_te_id, &m_gs_id, &m_fs_id, &m_po_id)) 1210348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1210448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* None of the test programs should ever build successfully */ 1210548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.getLog() << tcu::TestLog::Message 1210648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << "A program object, consisting of the following shaders, has linked" 1210748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " correctly. One of the shaders defines a subroutine uniform but does " 1210848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "not implement any function that matches subroutine type of the uniform." 1210948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " This should have resulted in a compilation/link-time error.\n" 1211048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1211148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "Vertex shader:\n" 1211248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1211348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << vs_body << "\n" 1211448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "Tessellation control shader:\n" 1211548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1211648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << tc_body << "\n" 1211748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "Tessellation evaluation shader:\n" 1211848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1211948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << te_body << "\n" 1212048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "Geometry shader:\n" 1212148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1212248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << gs_body << "\n" 1212348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "Fragment shader:\n" 1212448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1212548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << fs_body << tcu::TestLog::EndMessage; 1212648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1212748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_has_test_passed = false; 1212848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1212948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 1213048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1213148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Retrieves fragment shader body. 1213248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1213348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param include_invalid_subroutine_uniform_declaration true if the shader should declare 1213448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * a subroutine uniform without 1213548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * a matching subroutine, false otherwise. 1213648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1213748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return Requested string. 1213848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 1213948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosstd::string NegativeTest5::getFragmentShaderBody(bool include_invalid_subroutine_uniform_declaration) const 1214048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 1214148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::stringstream result_sstream; 1214248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1214348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "#version 400\n" 1214448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1214548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "#extension GL_ARB_shader_subroutine : require\n" 1214648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n"; 1214748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1214848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (include_invalid_subroutine_uniform_declaration) 1214948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1215048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "subroutine void subroutineTestTypeFS(out vec4 test);\n" 1215148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1215248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine uniform subroutineTestTypeFS test_subroutineFS;\n"; 1215348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos }; 1215448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1215548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "\n" 1215648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "out vec4 result;\n" 1215748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1215848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void main()\n" 1215948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n"; 1216048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1216148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (include_invalid_subroutine_uniform_declaration) 1216248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1216348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << " test_subroutineFS(result);\n"; 1216448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1216548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else 1216648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1216748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << " result = vec4(0, 1, 2, 3);\n"; 1216848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1216948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1217048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "}\n"; 1217148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1217248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return result_sstream.str(); 1217348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 1217448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1217548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Retrieves geometry shader body. 1217648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1217748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param include_invalid_subroutine_uniform_declaration true if the shader should declare 1217848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * a subroutine uniform without 1217948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * a matching subroutine, false otherwise. 1218048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1218148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return Requested string. 1218248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 1218348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosstd::string NegativeTest5::getGeometryShaderBody(bool include_invalid_subroutine_uniform_declaration) const 1218448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 1218548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::stringstream result_sstream; 1218648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1218748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "#version 400\n" 1218848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1218948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "#extension GL_ARB_shader_subroutine : require\n" 1219048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1219148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "layout (points) in;\n" 1219248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "layout (points, max_vertices = 1) out;\n" 1219348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n"; 1219448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1219548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (include_invalid_subroutine_uniform_declaration) 1219648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1219748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "subroutine void subroutineTestTypeGS(out vec4 test);\n" 1219848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1219948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine uniform subroutineTestTypeGS test_subroutineGS;\n"; 1220048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos }; 1220148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1220248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "\n" 1220348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void main()\n" 1220448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n"; 1220548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1220648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (include_invalid_subroutine_uniform_declaration) 1220748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1220848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << " test_subroutineGS(gl_Position);\n"; 1220948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1221048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else 1221148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1221248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << " gl_Position = vec4(0, 1, 2, 3);\n"; 1221348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1221448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1221548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "EmitVertex();\n" 1221648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n"; 1221748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1221848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return result_sstream.str(); 1221948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 1222048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1222148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Retrieves tessellation control shader body. 1222248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1222348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param include_invalid_subroutine_uniform_declaration true if the shader should declare 1222448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * a subroutine uniform without 1222548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * a matching subroutine, false otherwise. 1222648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1222748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return Requested string. 1222848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 1222948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosstd::string NegativeTest5::getTessellationControlShaderBody(bool include_invalid_subroutine_uniform_declaration) const 1223048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 1223148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::stringstream result_sstream; 1223248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1223348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "#version 400\n" 1223448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1223548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "#extension GL_ARB_shader_subroutine : require\n" 1223648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1223748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "layout (vertices = 4) out;\n" 1223848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n"; 1223948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1224048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (include_invalid_subroutine_uniform_declaration) 1224148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1224248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "subroutine void subroutineTestTypeTC(out vec4 test);\n" 1224348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1224448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine uniform subroutineTestTypeTC test_subroutineTC;\n"; 1224548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos }; 1224648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1224748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "\n" 1224848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void main()\n" 1224948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n"; 1225048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1225148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (include_invalid_subroutine_uniform_declaration) 1225248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1225348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << " test_subroutineTC(gl_out[gl_InvocationID].gl_Position);\n"; 1225448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1225548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else 1225648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1225748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << " gl_out[gl_InvocationID].gl_Position = vec4(0, 1, 2, 3);\n"; 1225848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1225948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1226048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "}\n"; 1226148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1226248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return result_sstream.str(); 1226348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 1226448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1226548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Retrieves tessellation evaluation body. 1226648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1226748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param include_invalid_subroutine_uniform_declaration true if the shader should declare 1226848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * a subroutine uniform without 1226948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * a matching subroutine, false otherwise. 1227048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1227148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return Requested string. 1227248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 1227348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosstd::string NegativeTest5::getTessellationEvaluationShaderBody( 1227448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos bool include_invalid_subroutine_uniform_declaration) const 1227548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 1227648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::stringstream result_sstream; 1227748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1227848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "#version 400\n" 1227948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1228048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "#extension GL_ARB_shader_subroutine : require\n" 1228148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1228248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "layout (quads) in;\n" 1228348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n"; 1228448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1228548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (include_invalid_subroutine_uniform_declaration) 1228648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1228748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "subroutine void subroutineTestTypeTE(out vec4 test);\n" 1228848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1228948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine uniform subroutineTestTypeTE test_subroutineTE;\n"; 1229048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos }; 1229148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1229248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "\n" 1229348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void main()\n" 1229448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n"; 1229548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1229648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (include_invalid_subroutine_uniform_declaration) 1229748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1229848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << " test_subroutineTE(gl_Position);\n"; 1229948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1230048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else 1230148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1230248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << " gl_Position = vec4(0, 1, 2, 3);\n"; 1230348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1230448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1230548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "}\n"; 1230648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1230748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return result_sstream.str(); 1230848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 1230948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1231048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Retrieves vertex shader body. 1231148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1231248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param include_invalid_subroutine_uniform_declaration true if the shader should declare 1231348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * a subroutine uniform without 1231448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * a matching subroutine, false otherwise. 1231548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1231648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return Requested string. 1231748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 1231848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosstd::string NegativeTest5::getVertexShaderBody(bool include_invalid_subroutine_uniform_declaration) const 1231948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 1232048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::stringstream result_sstream; 1232148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1232248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "#version 400\n" 1232348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1232448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "#extension GL_ARB_shader_subroutine : require\n" 1232548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n"; 1232648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1232748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (include_invalid_subroutine_uniform_declaration) 1232848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1232948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "subroutine void subroutineTestTypeVS(out vec4 test);\n" 1233048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1233148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine uniform subroutineTestTypeVS test_subroutineVS;\n"; 1233248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos }; 1233348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1233448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "\n" 1233548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void main()\n" 1233648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n"; 1233748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1233848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (include_invalid_subroutine_uniform_declaration) 1233948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1234048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << " test_subroutineVS(gl_Position);\n"; 1234148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1234248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else 1234348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1234448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << " gl_Position = vec4(0, 1, 2, 3);\n"; 1234548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1234648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1234748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "}\n"; 1234848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1234948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return result_sstream.str(); 1235048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 1235148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1235248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Executes test iteration. 1235348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1235448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed. 1235548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos */ 1235648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulostcu::TestNode::IterateResult NegativeTest5::iterate() 1235748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 1235848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Do not execute the test if GL_ARB_shader_subroutine is not supported */ 1235948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_shader_subroutine")) 1236048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1236148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos throw tcu::NotSupportedError("GL_ARB_shader_subroutine is not supported."); 1236248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1236348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1236448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Iterate over all shader stages. Iteration-specific shader stage defines a subroutine type & 1236548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * a corresponding subroutine uniform, for which no compatible subroutines are available. All 1236648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * other shader stages are defined correctly. 1236748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos */ 1236848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (int shader_stage = static_cast<int>(Utils::SHADER_STAGE_FIRST); 1236948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos shader_stage < static_cast<int>(Utils::SHADER_STAGE_COUNT); ++shader_stage) 1237048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1237148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos executeIteration(static_cast<Utils::_shader_stage>(shader_stage)); 1237248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos deinitIteration(); 1237348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } /* for (all shader stages) */ 1237448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1237548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* All done */ 1237648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_has_test_passed) 1237748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1237848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 1237948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1238048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else 1238148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1238248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 1238348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1238448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1238548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return STOP; 1238648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 1238748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1238848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Constructor. 1238948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1239048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param context Rendering context. 1239148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1239248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 1239348087f5f0eb08759ee763f98daf3b34becb74559Pyry HaulosNegativeTest6::NegativeTest6(deqp::Context& context) 1239448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos : TestCase(context, "two_duplicate_functions_one_being_a_subroutine", 1239548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "Verifies that a link- or compile-time error occurs if any shader in " 1239648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "a program object includes two functions with the same name and one " 1239748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "of which is associated with a subroutine type.") 1239848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_fs_id(0) 1239948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_gs_id(0) 1240048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_has_test_passed(true) 1240148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_po_id(0) 1240248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_tc_id(0) 1240348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_te_id(0) 1240448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_vs_id(0) 1240548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 1240648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Left blank intentionally */ 1240748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 1240848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1240948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Deinitializes all GL objects that may have been created during test execution */ 1241048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid NegativeTest6::deinit() 1241148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 1241248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos deinitIteration(); 1241348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 1241448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1241548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Deinitializes all GL objects that may have been created during a single test 1241648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * iteration. 1241748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos ***/ 1241848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid NegativeTest6::deinitIteration() 1241948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 1242048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1242148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1242248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_fs_id != 0) 1242348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1242448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteShader(m_fs_id); 1242548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1242648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_fs_id = 0; 1242748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1242848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1242948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_gs_id != 0) 1243048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1243148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteShader(m_gs_id); 1243248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1243348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_gs_id = 0; 1243448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1243548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1243648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_po_id != 0) 1243748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1243848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteProgram(m_po_id); 1243948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1244048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_po_id = 0; 1244148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1244248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1244348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_tc_id != 0) 1244448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1244548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteShader(m_tc_id); 1244648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1244748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_tc_id = 0; 1244848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1244948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1245048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_te_id != 0) 1245148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1245248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteShader(m_te_id); 1245348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1245448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_te_id = 0; 1245548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1245648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1245748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_vs_id != 0) 1245848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1245948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteShader(m_vs_id); 1246048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1246148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_vs_id = 0; 1246248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1246348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 1246448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1246548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Executes a single test iteration. 1246648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1246748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * If the iteration fails, m_has_test_passed will be set to false. 1246848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1246948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param shader_stage Shader stage, for which two duplicate functions 1247048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * (one additionally marked as subroutine) should 1247148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * be defined. 1247248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 1247348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid NegativeTest6::executeIteration(const Utils::_shader_stage& shader_stage) 1247448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 1247548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::string fs_body = getFragmentShaderBody(shader_stage == Utils::SHADER_STAGE_FRAGMENT); 1247648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::string gs_body = getGeometryShaderBody(shader_stage == Utils::SHADER_STAGE_GEOMETRY); 1247748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::string tc_body = getTessellationControlShaderBody(shader_stage == Utils::SHADER_STAGE_TESSELLATION_CONTROL); 1247848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::string te_body = 1247948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos getTessellationEvaluationShaderBody(shader_stage == Utils::SHADER_STAGE_TESSELLATION_EVALUATION); 1248048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::string vs_body = getVertexShaderBody(shader_stage == Utils::SHADER_STAGE_VERTEX); 1248148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1248248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (Utils::buildProgram(m_context.getRenderContext().getFunctions(), vs_body, tc_body, te_body, gs_body, fs_body, 1248348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos DE_NULL, /* xfb_varyings */ 1248448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos DE_NULL, /* n_xfb_varyings */ 1248548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos &m_vs_id, &m_tc_id, &m_te_id, &m_gs_id, &m_fs_id, &m_po_id)) 1248648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1248748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* None of the test programs should ever build successfully */ 1248848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.getLog() << tcu::TestLog::Message 1248948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << "A program object, consisting of the following shaders, has linked" 1249048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " correctly. This is invalid, because one of the shaders defines two" 1249148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " functions with the same name, with an exception that one of the" 1249248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " functions is marked as a subroutine.\n" 1249348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1249448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "Vertex shader:\n" 1249548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1249648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << vs_body << "\n" 1249748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "Tessellation control shader:\n" 1249848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1249948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << tc_body << "\n" 1250048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "Tessellation evaluation shader:\n" 1250148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1250248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << te_body << "\n" 1250348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "Geometry shader:\n" 1250448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1250548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << gs_body << "\n" 1250648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "Fragment shader:\n" 1250748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1250848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << fs_body << tcu::TestLog::EndMessage; 1250948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1251048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_has_test_passed = false; 1251148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1251248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 1251348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1251448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Retrieves fragment shader body. 1251548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1251648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param include_invalid_declaration true if the shader should include duplicate function 1251748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * declaration. 1251848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1251948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return Requested string. 1252048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 1252148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosstd::string NegativeTest6::getFragmentShaderBody(bool include_invalid_declaration) const 1252248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 1252348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::stringstream result_sstream; 1252448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1252548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "#version 400\n" 1252648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1252748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "#extension GL_ARB_shader_subroutine : require\n" 1252848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n"; 1252948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1253048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (include_invalid_declaration) 1253148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1253248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "subroutine void subroutineTestTypeFS(out vec4 test);\n" 1253348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1253448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine(subroutineTestTypeFS) void test_impl1(out vec4 test)\n" 1253548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 1253648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " test = vec4(1, 2, 3, 4);\n" 1253748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 1253848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1253948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void test_impl1(out vec4 test)\n" 1254048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 1254148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " test = vec4(2, 3, 4, 5);\n" 1254248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 1254348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1254448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine uniform subroutineTestTypeFS test_subroutineFS;\n"; 1254548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos }; 1254648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1254748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "\n" 1254848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "out vec4 result;\n" 1254948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1255048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void main()\n" 1255148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n"; 1255248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1255348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (include_invalid_declaration) 1255448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1255548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << " test_subroutineFS(result);\n"; 1255648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1255748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else 1255848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1255948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << " result = vec4(0, 1, 2, 3);\n"; 1256048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1256148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1256248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "}\n"; 1256348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1256448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return result_sstream.str(); 1256548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 1256648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1256748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Retrieves geometry shader body. 1256848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1256948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param include_invalid_declaration true if the shader should include duplicate function 1257048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * declaration. 1257148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1257248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return Requested string. 1257348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 1257448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosstd::string NegativeTest6::getGeometryShaderBody(bool include_invalid_declaration) const 1257548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 1257648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::stringstream result_sstream; 1257748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1257848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "#version 400\n" 1257948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1258048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "#extension GL_ARB_shader_subroutine : require\n" 1258148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1258248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "layout (points) in;\n" 1258348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "layout (points, max_vertices = 1) out;\n" 1258448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n"; 1258548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1258648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (include_invalid_declaration) 1258748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1258848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "subroutine void subroutineTestTypeGS(out vec4 test);\n" 1258948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1259048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine(subroutineTestTypeGS) void test_impl1(out vec4 test)\n" 1259148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 1259248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " test = vec4(1, 2, 3, 4);\n" 1259348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 1259448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1259548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void test_impl1(out vec4 test)\n" 1259648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 1259748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " test = vec4(2, 3, 4, 5);\n" 1259848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 1259948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1260048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine uniform subroutineTestTypeGS test_subroutineGS;\n"; 1260148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos }; 1260248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1260348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "\n" 1260448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void main()\n" 1260548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n"; 1260648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1260748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (include_invalid_declaration) 1260848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1260948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << " test_subroutineGS(gl_Position);\n"; 1261048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1261148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else 1261248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1261348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << " gl_Position = vec4(0, 1, 2, 3);\n"; 1261448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1261548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1261648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "EmitVertex();\n" 1261748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n"; 1261848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1261948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return result_sstream.str(); 1262048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 1262148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1262248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Retrieves tessellation control shader body. 1262348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1262448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param include_invalid_declaration true if the shader should include duplicate function 1262548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * declaration. 1262648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1262748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return Requested string. 1262848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 1262948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosstd::string NegativeTest6::getTessellationControlShaderBody(bool include_invalid_declaration) const 1263048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 1263148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::stringstream result_sstream; 1263248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1263348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "#version 400\n" 1263448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1263548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "#extension GL_ARB_shader_subroutine : require\n" 1263648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1263748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "layout (vertices = 4) out;\n" 1263848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n"; 1263948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1264048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (include_invalid_declaration) 1264148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1264248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "subroutine void subroutineTestTypeTC(out vec4 test);\n" 1264348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1264448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine(subroutineTestTypeTC) void test_impl1(out vec4 test)\n" 1264548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 1264648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " test = vec4(1, 2, 3, 4);\n" 1264748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 1264848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1264948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void test_impl1(out vec4 test)\n" 1265048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 1265148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " test = vec4(2, 3, 4, 5);\n" 1265248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 1265348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1265448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine uniform subroutineTestTypeTC test_subroutineTC;\n"; 1265548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos }; 1265648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1265748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "\n" 1265848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void main()\n" 1265948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n"; 1266048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1266148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (include_invalid_declaration) 1266248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1266348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << " test_subroutineTC(gl_out[gl_InvocationID].gl_Position);\n"; 1266448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1266548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else 1266648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1266748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << " gl_out[gl_InvocationID].gl_Position = vec4(0, 1, 2, 3);\n"; 1266848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1266948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1267048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "}\n"; 1267148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1267248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return result_sstream.str(); 1267348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 1267448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1267548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Retrieves tessellation evaluation body. 1267648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1267748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param include_invalid_declaration true if the shader should include duplicate function 1267848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * declaration. 1267948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1268048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return Requested string. 1268148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 1268248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosstd::string NegativeTest6::getTessellationEvaluationShaderBody(bool include_invalid_declaration) const 1268348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 1268448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::stringstream result_sstream; 1268548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1268648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "#version 400\n" 1268748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1268848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "#extension GL_ARB_shader_subroutine : require\n" 1268948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1269048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "layout (quads) in;\n" 1269148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n"; 1269248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1269348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (include_invalid_declaration) 1269448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1269548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "subroutine void subroutineTestTypeTE(out vec4 test);\n" 1269648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1269748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine(subroutineTestTypeTE) void test_impl1(out vec4 test)\n" 1269848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 1269948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " test = vec4(1, 2, 3, 4);\n" 1270048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 1270148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1270248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void test_impl1(out vec4 test)\n" 1270348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 1270448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " test = vec4(2, 3, 4, 5);\n" 1270548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 1270648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1270748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine uniform subroutineTestTypeTE test_subroutineTE;\n"; 1270848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos }; 1270948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1271048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "\n" 1271148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void main()\n" 1271248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n"; 1271348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1271448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (include_invalid_declaration) 1271548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1271648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << " test_subroutineTE(gl_Position);\n"; 1271748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1271848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else 1271948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1272048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << " gl_Position = vec4(0, 1, 2, 3);\n"; 1272148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1272248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1272348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "}\n"; 1272448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1272548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return result_sstream.str(); 1272648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 1272748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1272848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Retrieves vertex shader body. 1272948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1273048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param include_invalid_declaration true if the shader should include duplicate function 1273148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * declaration. 1273248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1273348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return Requested string. 1273448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 1273548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosstd::string NegativeTest6::getVertexShaderBody(bool include_invalid_declaration) const 1273648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 1273748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::stringstream result_sstream; 1273848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1273948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "#version 400\n" 1274048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1274148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "#extension GL_ARB_shader_subroutine : require\n" 1274248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n"; 1274348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1274448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (include_invalid_declaration) 1274548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1274648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "subroutine void subroutineTestTypeVS(out vec4 test);\n" 1274748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1274848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine(subroutineTestTypeVS) void test_impl1(out vec4 test)\n" 1274948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 1275048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " test = vec4(1, 2, 3, 4);\n" 1275148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 1275248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1275348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void test_impl1(out vec4 test)\n" 1275448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 1275548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " test = vec4(2, 3, 4, 5);\n" 1275648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 1275748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1275848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine uniform subroutineTestTypeVS test_subroutineVS;\n"; 1275948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos }; 1276048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1276148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "\n" 1276248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void main()\n" 1276348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n"; 1276448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1276548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (include_invalid_declaration) 1276648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1276748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << " test_subroutineVS(gl_Position);\n"; 1276848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1276948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else 1277048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1277148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << " gl_Position = vec4(0, 1, 2, 3);\n"; 1277248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1277348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1277448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "}\n"; 1277548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1277648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return result_sstream.str(); 1277748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 1277848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1277948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Executes test iteration. 1278048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1278148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed. 1278248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos */ 1278348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulostcu::TestNode::IterateResult NegativeTest6::iterate() 1278448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 1278548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Do not execute the test if GL_ARB_shader_subroutine is not supported */ 1278648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_shader_subroutine")) 1278748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1278848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos throw tcu::NotSupportedError("GL_ARB_shader_subroutine is not supported."); 1278948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1279048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1279148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Iterate over all shader stages. In each iteration, we will inject invalid 1279248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * duplicate function declarations to iteration-specific shader stage. All other 1279348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * shader stages will be assigned valid bodies. Test should fail if the program 1279448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * links successfully. 1279548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos */ 1279648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (int shader_stage = static_cast<int>(Utils::SHADER_STAGE_FIRST); 1279748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos shader_stage < static_cast<int>(Utils::SHADER_STAGE_COUNT); ++shader_stage) 1279848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1279948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos executeIteration(static_cast<Utils::_shader_stage>(shader_stage)); 1280048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos deinitIteration(); 1280148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } /* for (all shader stages) */ 1280248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1280348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* All done */ 1280448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_has_test_passed) 1280548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1280648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 1280748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1280848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else 1280948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1281048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 1281148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1281248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1281348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return STOP; 1281448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 1281548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1281648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Constructor 1281748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1281848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param context CTS context 1281948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 1282048087f5f0eb08759ee763f98daf3b34becb74559Pyry HaulosNegativeTest7::NegativeTest7(deqp::Context& context) 1282148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos : TestCase(context, "recursion", "Verify that it is not possible to build program with recursing subroutines") 1282248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_program_id(0) 1282348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_vertex_shader_id(0) 1282448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 1282548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Nothing to be done here */ 1282648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 1282748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1282848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Deinitializes all GL objects that may have been created during test execution 1282948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1283048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 1283148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid NegativeTest7::deinit() 1283248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 1283348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1283448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1283548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_program_id != 0) 1283648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1283748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteProgram(m_program_id); 1283848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1283948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_program_id = 0; 1284048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1284148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1284248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_vertex_shader_id != 0) 1284348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1284448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteShader(m_vertex_shader_id); 1284548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1284648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_vertex_shader_id = 0; 1284748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1284848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 1284948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1285048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Executes test iteration. 1285148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1285248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed. 1285348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 1285448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulostcu::TestNode::IterateResult NegativeTest7::iterate() 1285548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 1285648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLchar* vertex_shader_with_static_recursion = 1285748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "#version 400\n" 1285848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1285948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "#extension GL_ARB_shader_subroutine : require\n" 1286048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1286148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "precision highp float;\n" 1286248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1286348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine vec4 routine_type(in vec4 data, in uint control);\n" 1286448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1286548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine (routine_type) vec4 power_routine(in vec4 data, in uint control)\n" 1286648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 1286748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " if (0 != control)\n" 1286848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " {\n" 1286948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " return data * power_routine(data, control - 1);\n" 1287048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " }\n" 1287148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " else\n" 1287248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " {\n" 1287348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " return vec4(1, 1, 1, 1);\n" 1287448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " }\n" 1287548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 1287648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1287748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine (routine_type) vec4 select_routine(in vec4 data, in uint control)\n" 1287848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 1287948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " if (0 == control)\n" 1288048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " {\n" 1288148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " return data.rrrr;\n" 1288248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " }\n" 1288348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " else if (1 == control)\n" 1288448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " {\n" 1288548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " return data.gggg;\n" 1288648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " }\n" 1288748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " else if (2 == control)\n" 1288848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " {\n" 1288948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " return data.bbbb;\n" 1289048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " }\n" 1289148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " else\n" 1289248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " {\n" 1289348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " return data.aaaa;\n" 1289448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " }\n" 1289548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 1289648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1289748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine uniform routine_type routine;\n" 1289848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1289948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "uniform vec4 uni_value;\n" 1290048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "uniform uint uni_control;\n" 1290148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1290248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "out vec4 out_result;\n" 1290348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1290448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void main()\n" 1290548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 1290648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " out_result = routine(uni_value, uni_control);\n" 1290748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 1290848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n"; 1290948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1291048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLchar* vertex_shader_with_dynamic_recursion = 1291148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "#version 400\n" 1291248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1291348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "#extension GL_ARB_shader_subroutine : require\n" 1291448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1291548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "precision highp float;\n" 1291648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1291748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine vec4 routine_type(in vec4 data);\n" 1291848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1291948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine uniform routine_type routine;\n" 1292048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1292148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine (routine_type) vec4 div_by_2(in vec4 data)\n" 1292248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 1292348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " return data / 2;\n" 1292448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 1292548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1292648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine (routine_type) vec4 div_routine_result_by_2(in vec4 data)\n" 1292748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 1292848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " return routine(data) / 2;\n" 1292948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 1293048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1293148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "uniform vec4 uni_value;\n" 1293248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1293348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "out vec4 out_result;\n" 1293448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1293548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void main()\n" 1293648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 1293748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " out_result = routine(uni_value);\n" 1293848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 1293948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n"; 1294048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1294148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLchar* vertex_shader_with_subroutine_function_recursion = 1294248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "#version 400\n" 1294348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1294448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "#extension GL_ARB_shader_subroutine : require\n" 1294548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1294648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "precision highp float;\n" 1294748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1294848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine vec4 routine_type(in vec4 data);\n" 1294948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1295048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine uniform routine_type routine;\n" 1295148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1295248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "vec4 function(in vec4 data)\n" 1295348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 1295448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " return routine(data) + vec4(0.5, 0.5, 0.5, 0.5);\n" 1295548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 1295648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1295748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine (routine_type) vec4 routine_a(in vec4 data)\n" 1295848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 1295948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " return function(data) / 2;\n" 1296048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 1296148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1296248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine (routine_type) vec4 routine_b(in vec4 data)\n" 1296348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 1296448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " return routine_a(data) * 2;\n" 1296548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 1296648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1296748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "uniform vec4 uni_value;\n" 1296848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1296948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "out vec4 out_result;\n" 1297048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1297148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void main()\n" 1297248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 1297348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " out_result = routine(uni_value);\n" 1297448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 1297548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n"; 1297648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1297748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos bool result = true; 1297848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1297948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (false == test(vertex_shader_with_subroutine_function_recursion, "routine_a")) 1298048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1298148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = false; 1298248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1298348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1298448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (false == test(vertex_shader_with_dynamic_recursion, "div_routine_result_by_2")) 1298548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1298648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = false; 1298748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1298848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1298948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (false == test(vertex_shader_with_static_recursion, "power_routine")) 1299048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1299148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = false; 1299248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1299348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1299448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Set result */ 1299548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (true == result) 1299648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1299748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 1299848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1299948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else 1300048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1300148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 1300248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1300348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1300448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Done */ 1300548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return tcu::TestNode::STOP; 1300648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 1300748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1300848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Try to build program from vertex shader code. 1300948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1301048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param vertex_shader_code Source code of vertex shader 1301148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param name_of_recursive_routine Name of subroutine that should cause link failure due to recursion 1301248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1301348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return true build process failed, false otherwise 1301448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 1301548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosbool NegativeTest7::test(const GLchar* vertex_shader_code, const GLchar* name_of_recursive_routine) 1301648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 1301748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1301848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos bool result = true; 1301948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos static const GLchar* varying_name = "out_result"; 1302048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1302148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Try to build program */ 1302248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (true == Utils::buildProgram(gl, vertex_shader_code, "", "", "", "", &varying_name /* varying_names */, 1302348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1 /* n_varyings */, &m_vertex_shader_id, 0, 0, 0, 0, &m_program_id)) 1302448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1302548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Success is considered an error */ 1302648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1302748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::program program(m_context); 1302848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLuint index = 0; 1302948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1303048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos program.build(0, 0, 0, 0, 0, vertex_shader_code, 0, 0); 1303148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1303248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Verify that recursive subroutine is active */ 1303348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos try 1303448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1303548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos index = program.getSubroutineIndex(name_of_recursive_routine, GL_VERTEX_SHADER); 1303648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1303748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos catch (const std::exception& exc) 1303848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1303948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Something wrong with shader or compilation */ 1304048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_context.getTestContext().getLog() 1304148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << tcu::TestLog::Message << "It is expected that subroutine: \n" 1304248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << name_of_recursive_routine 1304348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << " is considered active. This subroutine is potentially recursive and should cause link failure." 1304448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << tcu::TestLog::EndMessage; 1304548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1304648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos throw exc; 1304748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1304848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1304948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Subsoutine is active, however linking should fail */ 1305048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_context.getTestContext().getLog() 1305148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << tcu::TestLog::Message << "Error. Program with potentially recursive subroutine, " 1305248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << name_of_recursive_routine << ", which is active, index: " << index << ", has been built successfully.\n" 1305348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << vertex_shader_code << tcu::TestLog::EndMessage; 1305448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1305548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = false; 1305648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1305748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1305848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Delete program and shader */ 1305948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos deinit(); 1306048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1306148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Done */ 1306248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return result; 1306348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 1306448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1306548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Constructor. 1306648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1306748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param context Rendering context. 1306848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1306948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 1307048087f5f0eb08759ee763f98daf3b34becb74559Pyry HaulosNegativeTest8::NegativeTest8(deqp::Context& context) 1307148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos : TestCase(context, "subroutine_wo_body", "Verifies that a compile- or link-time error occurs if a function " 1307248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "declared as a subroutine does not include a body.") 1307348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_fs_id(0) 1307448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_gs_id(0) 1307548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_has_test_passed(true) 1307648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_po_id(0) 1307748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_tc_id(0) 1307848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_te_id(0) 1307948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_vs_id(0) 1308048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 1308148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Left blank intentionally */ 1308248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 1308348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1308448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Deinitializes all GL objects that may have been created during test execution */ 1308548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid NegativeTest8::deinit() 1308648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 1308748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos deinitIteration(); 1308848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 1308948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1309048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Deinitializes all GL objects that may have been created during a single test 1309148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * iteration. 1309248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos ***/ 1309348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid NegativeTest8::deinitIteration() 1309448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 1309548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1309648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1309748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_fs_id != 0) 1309848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1309948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteShader(m_fs_id); 1310048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1310148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_fs_id = 0; 1310248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1310348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1310448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_gs_id != 0) 1310548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1310648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteShader(m_gs_id); 1310748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1310848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_gs_id = 0; 1310948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1311048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1311148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_po_id != 0) 1311248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1311348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteProgram(m_po_id); 1311448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1311548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_po_id = 0; 1311648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1311748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1311848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_tc_id != 0) 1311948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1312048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteShader(m_tc_id); 1312148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1312248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_tc_id = 0; 1312348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1312448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1312548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_te_id != 0) 1312648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1312748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteShader(m_te_id); 1312848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1312948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_te_id = 0; 1313048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1313148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1313248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_vs_id != 0) 1313348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1313448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteShader(m_vs_id); 1313548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1313648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_vs_id = 0; 1313748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1313848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 1313948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1314048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Executes a single test iteration. 1314148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1314248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * If the iteration fails, m_has_test_passed will be set to false. 1314348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1314448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param shader_stage Shader stage, for which two duplicate functions 1314548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * (one additionally marked as subroutine) should 1314648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * be defined. 1314748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 1314848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid NegativeTest8::executeIteration(const Utils::_shader_stage& shader_stage) 1314948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 1315048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::string fs_body = getFragmentShaderBody(shader_stage == Utils::SHADER_STAGE_FRAGMENT); 1315148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::string gs_body = getGeometryShaderBody(shader_stage == Utils::SHADER_STAGE_GEOMETRY); 1315248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::string tc_body = getTessellationControlShaderBody(shader_stage == Utils::SHADER_STAGE_TESSELLATION_CONTROL); 1315348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::string te_body = 1315448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos getTessellationEvaluationShaderBody(shader_stage == Utils::SHADER_STAGE_TESSELLATION_EVALUATION); 1315548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::string vs_body = getVertexShaderBody(shader_stage == Utils::SHADER_STAGE_VERTEX); 1315648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1315748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (Utils::buildProgram(m_context.getRenderContext().getFunctions(), vs_body, tc_body, te_body, gs_body, fs_body, 1315848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos DE_NULL, /* xfb_varyings */ 1315948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos DE_NULL, /* n_xfb_varyings */ 1316048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos &m_vs_id, &m_tc_id, &m_te_id, &m_gs_id, &m_fs_id, &m_po_id)) 1316148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1316248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* None of the test programs should ever build successfully */ 1316348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.getLog() << tcu::TestLog::Message 1316448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << "A program object consisting of FS+GS+TC+TE+VS stages has linked successfully, " 1316548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "even though one of the shaders only defines a subroutine that lacks any body." 1316648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1316748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "Vertex shader:\n" 1316848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1316948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << vs_body << "\n" 1317048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "Tessellation control shader:\n" 1317148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1317248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << tc_body << "\n" 1317348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "Tessellation evaluation shader:\n" 1317448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1317548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << te_body << "\n" 1317648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "Geometry shader:\n" 1317748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1317848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << gs_body << "\n" 1317948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "Fragment shader:\n" 1318048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1318148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << fs_body << tcu::TestLog::EndMessage; 1318248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1318348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_has_test_passed = false; 1318448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1318548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 1318648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1318748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Retrieves fragment shader body. 1318848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1318948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param include_invalid_declaration true if a subroutine prototype should be included in 1319048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * the shader, false to skip it. 1319148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1319248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return Requested string. 1319348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 1319448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosstd::string NegativeTest8::getFragmentShaderBody(bool include_invalid_declaration) const 1319548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 1319648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::stringstream result_sstream; 1319748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1319848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "#version 400\n" 1319948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1320048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "#extension GL_ARB_shader_subroutine : require\n" 1320148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n"; 1320248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1320348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (include_invalid_declaration) 1320448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1320548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "subroutine void subroutineTestTypeFS(out vec4 test);\n" 1320648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1320748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine(subroutineTestTypeFS) void test_impl1(out vec4 test);\n" 1320848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1320948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine uniform subroutineTestTypeFS test_subroutineFS;\n"; 1321048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos }; 1321148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1321248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "\n" 1321348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "out vec4 result;\n" 1321448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1321548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void main()\n" 1321648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n"; 1321748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1321848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (include_invalid_declaration) 1321948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1322048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << " test_subroutineFS(result);\n"; 1322148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1322248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else 1322348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1322448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << " result = vec4(0, 1, 2, 3);\n"; 1322548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1322648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1322748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "}\n"; 1322848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1322948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return result_sstream.str(); 1323048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 1323148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1323248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Retrieves geometry shader body. 1323348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1323448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param include_invalid_declaration true if a subroutine prototype should be included in 1323548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * the shader, false to skip it. 1323648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1323748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return Requested string. 1323848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 1323948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosstd::string NegativeTest8::getGeometryShaderBody(bool include_invalid_declaration) const 1324048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 1324148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::stringstream result_sstream; 1324248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1324348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "#version 400\n" 1324448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1324548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "#extension GL_ARB_shader_subroutine : require\n" 1324648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1324748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "layout (points) in;\n" 1324848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "layout (points, max_vertices = 1) out;\n" 1324948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n"; 1325048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1325148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (include_invalid_declaration) 1325248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1325348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "subroutine void subroutineTestTypeGS(out vec4 test);\n" 1325448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1325548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine(subroutineTestTypeGS) void test_impl1(out vec4 test);\n" 1325648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1325748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine uniform subroutineTestTypeGS test_subroutineGS;\n"; 1325848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos }; 1325948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1326048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "\n" 1326148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void main()\n" 1326248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n"; 1326348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1326448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (include_invalid_declaration) 1326548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1326648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << " test_subroutineGS(gl_Position);\n"; 1326748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1326848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else 1326948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1327048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << " gl_Position = vec4(0, 1, 2, 3);\n"; 1327148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1327248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1327348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "EmitVertex();\n" 1327448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n"; 1327548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1327648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return result_sstream.str(); 1327748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 1327848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1327948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Retrieves tessellation control shader body. 1328048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1328148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param include_invalid_declaration true if a subroutine prototype should be included in 1328248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * the shader, false to skip it. 1328348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1328448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return Requested string. 1328548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 1328648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosstd::string NegativeTest8::getTessellationControlShaderBody(bool include_invalid_declaration) const 1328748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 1328848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::stringstream result_sstream; 1328948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1329048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "#version 400\n" 1329148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1329248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "#extension GL_ARB_shader_subroutine : require\n" 1329348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1329448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "layout (vertices = 4) out;\n" 1329548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n"; 1329648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1329748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (include_invalid_declaration) 1329848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1329948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "subroutine void subroutineTestTypeTC(out vec4 test);\n" 1330048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1330148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine(subroutineTestTypeTC) void test_impl1(out vec4 test);\n" 1330248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1330348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine uniform subroutineTestTypeTC test_subroutineTC;\n"; 1330448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos }; 1330548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1330648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "\n" 1330748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void main()\n" 1330848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n"; 1330948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1331048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (include_invalid_declaration) 1331148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1331248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << " test_subroutineTC(gl_out[gl_InvocationID].gl_Position);\n"; 1331348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1331448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else 1331548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1331648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << " gl_out[gl_InvocationID].gl_Position = vec4(0, 1, 2, 3);\n"; 1331748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1331848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1331948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "}\n"; 1332048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1332148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return result_sstream.str(); 1332248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 1332348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1332448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Retrieves tessellation evaluation body. 1332548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1332648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param include_invalid_declaration true if a subroutine prototype should be included in 1332748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * the shader, false to skip it. 1332848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1332948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return Requested string. 1333048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 1333148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosstd::string NegativeTest8::getTessellationEvaluationShaderBody(bool include_invalid_declaration) const 1333248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 1333348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::stringstream result_sstream; 1333448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1333548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "#version 400\n" 1333648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1333748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "#extension GL_ARB_shader_subroutine : require\n" 1333848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1333948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "layout (quads) in;\n" 1334048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n"; 1334148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1334248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (include_invalid_declaration) 1334348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1334448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "subroutine void subroutineTestTypeTE(out vec4 test);\n" 1334548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1334648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine(subroutineTestTypeTE) void test_impl1(out vec4 test);\n" 1334748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1334848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine uniform subroutineTestTypeTE test_subroutineTE;\n"; 1334948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos }; 1335048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1335148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "\n" 1335248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void main()\n" 1335348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n"; 1335448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1335548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (include_invalid_declaration) 1335648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1335748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << " test_subroutineTE(gl_Position);\n"; 1335848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1335948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else 1336048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1336148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << " gl_Position = vec4(0, 1, 2, 3);\n"; 1336248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1336348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1336448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "}\n"; 1336548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1336648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return result_sstream.str(); 1336748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 1336848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1336948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Retrieves vertex shader body. 1337048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1337148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param include_invalid_declaration true if a subroutine prototype should be included in 1337248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * the shader, false to skip it. 1337348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1337448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return Requested string. 1337548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 1337648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosstd::string NegativeTest8::getVertexShaderBody(bool include_invalid_declaration) const 1337748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 1337848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::stringstream result_sstream; 1337948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1338048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "#version 400\n" 1338148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1338248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "#extension GL_ARB_shader_subroutine : require\n" 1338348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n"; 1338448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1338548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (include_invalid_declaration) 1338648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1338748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "subroutine void subroutineTestTypeVS(out vec4 test);\n" 1338848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1338948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine(subroutineTestTypeVS) void test_impl1(out vec4 test);\n" 1339048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1339148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine uniform subroutineTestTypeVS test_subroutineVS;\n"; 1339248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos }; 1339348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1339448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "\n" 1339548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void main()\n" 1339648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n"; 1339748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1339848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (include_invalid_declaration) 1339948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1340048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << " test_subroutineVS(gl_Position);\n"; 1340148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1340248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else 1340348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1340448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << " gl_Position = vec4(0, 1, 2, 3);\n"; 1340548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1340648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1340748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "}\n"; 1340848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1340948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return result_sstream.str(); 1341048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 1341148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1341248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Executes test iteration. 1341348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1341448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed. 1341548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos */ 1341648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulostcu::TestNode::IterateResult NegativeTest8::iterate() 1341748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 1341848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Do not execute the test if GL_ARB_shader_subroutine is not supported */ 1341948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_shader_subroutine")) 1342048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1342148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos throw tcu::NotSupportedError("GL_ARB_shader_subroutine is not supported."); 1342248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1342348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1342448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Iterate over all shader stages. For each iteration, iteration-specific shader stage 1342548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * will feature an invalid subroutine definition. Other shader stages will be assigned 1342648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * valid bodies. The test fails if a program built of such shaders links successfully. 1342748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos */ 1342848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (int shader_stage = static_cast<int>(Utils::SHADER_STAGE_FIRST); 1342948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos shader_stage < static_cast<int>(Utils::SHADER_STAGE_COUNT); ++shader_stage) 1343048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1343148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos executeIteration(static_cast<Utils::_shader_stage>(shader_stage)); 1343248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos deinitIteration(); 1343348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } /* for (all shader stages) */ 1343448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1343548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* All done */ 1343648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_has_test_passed) 1343748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1343848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 1343948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1344048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else 1344148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1344248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 1344348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1344448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1344548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return STOP; 1344648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 1344748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1344848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Constructor. 1344948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1345048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param context Rendering context. 1345148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 1345248087f5f0eb08759ee763f98daf3b34becb74559Pyry HaulosNegativeTest9::NegativeTest9(deqp::Context& context) 1345348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos : TestCase(context, "subroutines_cannot_be_assigned_float_int_values_or_be_compared", 1345448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "Make sure it is not possible to assign float/int to subroutine " 1345548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "uniform and that subroutine uniform values cannot be compared.") 1345648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_has_test_passed(true) 1345748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_po_id(0) 1345848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_vs_id(0) 1345948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 1346048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Left blank intentionally */ 1346148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 1346248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1346348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Deinitializes any GL objects that may have been created during 1346448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * test execution. 1346548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 1346648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid NegativeTest9::deinit() 1346748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 1346848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1346948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1347048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_po_id != 0) 1347148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1347248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteProgram(m_po_id); 1347348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1347448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_po_id = 0; 1347548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1347648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1347748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_vs_id != 0) 1347848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1347948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteShader(m_vs_id); 1348048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1348148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_vs_id = 0; 1348248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1348348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 1348448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1348548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Returns a literal corresponding to user-specified test case enum. 1348648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1348748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param test_case As per description. 1348848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1348948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return Requested string. 1349048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 1349148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosstd::string NegativeTest9::getTestCaseString(const _test_case& test_case) 1349248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 1349348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::string result = "?"; 1349448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1349548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos switch (test_case) 1349648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1349748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case TEST_CASE_INVALID_FLOAT_TO_SUBROUTINE_UNIFORM_ASSIGNMENT: 1349848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = "TEST_CASE_INVALID_FLOAT_TO_SUBROUTINE_UNIFORM_ASSIGNMENT"; 1349948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 1350048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case TEST_CASE_INVALID_INT_TO_SUBROUTINE_UNIFORM_ASSIGNMENT: 1350148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = "TEST_CASE_INVALID_INT_TO_SUBROUTINE_UNIFORM_ASSIGNMENT"; 1350248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 1350348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case TEST_CASE_INVALID_SUBROUTINE_UNIFORM_VALUE_COMPARISON: 1350448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = "TEST_CASE_INVALID_SUBROUTINE_UNIFORM_VALUE_COMPARISON"; 1350548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 1350648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos default: 1350748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 1350848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1350948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1351048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return result; 1351148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 1351248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1351348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Retrieves vertex shader body for user-specified test case. 1351448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1351548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param test_case As per description. 1351648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1351748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return Requested string. 1351848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 1351948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosstd::string NegativeTest9::getVertexShader(const _test_case& test_case) 1352048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 1352148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::stringstream result_sstream; 1352248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1352348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Form pre-amble */ 1352448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "#version 400\n" 1352548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1352648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "#extension GL_ARB_shader_subroutine : require\n" 1352748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1352848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Define a subroutine */ 1352948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine void subroutineType(inout vec4 test);\n" 1353048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1353148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine(subroutineType) void test_function(inout vec4 test)\n" 1353248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 1353348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " test += vec4(0, 1, 2, 3);\n" 1353448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 1353548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1353648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine uniform subroutineType function;\n" 1353748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n"; 1353848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1353948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Include case-specific implementation */ 1354048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos switch (test_case) 1354148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1354248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case TEST_CASE_INVALID_FLOAT_TO_SUBROUTINE_UNIFORM_ASSIGNMENT: 1354348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1354448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "void main()\n" 1354548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 1354648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " function = 1.0f;\n" 1354748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1354848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " function(gl_Position);\n" 1354948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n"; 1355048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1355148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 1355248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1355348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1355448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case TEST_CASE_INVALID_INT_TO_SUBROUTINE_UNIFORM_ASSIGNMENT: 1355548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1355648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "void main()\n" 1355748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 1355848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " function = 1;\n" 1355948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1356048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " function(gl_Position);\n" 1356148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n"; 1356248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1356348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 1356448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1356548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1356648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case TEST_CASE_INVALID_SUBROUTINE_UNIFORM_VALUE_COMPARISON: 1356748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1356848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "subroutine uniform subroutineType function2;\n" 1356948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1357048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void main()\n" 1357148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 1357248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " if (function == function2)\n" 1357348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " {\n" 1357448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " function(gl_Position);\n" 1357548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " }\n" 1357648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " else\n" 1357748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " {\n" 1357848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " function2(gl_Position);\n" 1357948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " }\n" 1358048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n"; 1358148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1358248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 1358348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1358448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1358548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos default: 1358648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 1358748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } /* switch (test_case) */ 1358848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1358948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Done */ 1359048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return result_sstream.str(); 1359148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 1359248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1359348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Executes test iteration. 1359448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1359548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed. 1359648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos */ 1359748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulostcu::TestNode::IterateResult NegativeTest9::iterate() 1359848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 1359948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1360048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1360148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Do not execute the test if GL_ARB_shader_subroutine is not supported */ 1360248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_shader_subroutine")) 1360348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1360448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos throw tcu::NotSupportedError("GL_ARB_shader_subroutine is not supported."); 1360548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1360648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1360748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Iterate over all test cases */ 1360848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (int test_case = static_cast<int>(TEST_CASE_FIRST); test_case != static_cast<int>(TEST_CASE_COUNT); ++test_case) 1360948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1361048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Try to build a program object using invalid vertex shader, specific to the 1361148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * iteration we're currently in */ 1361248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::string vs_body = getVertexShader(static_cast<_test_case>(test_case)); 1361348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1361448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (ShaderSubroutine::Utils::buildProgram(gl, vs_body, "", /* tc_body */ 1361548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "", /* te_body */ 1361648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "", /* gs_body */ 1361748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "", /* fs_body */ 1361848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos DE_NULL, /* xfb_varyings */ 1361948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 0, /* n_xfb_varyings */ 1362048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos &m_vs_id, DE_NULL, /* out_tc_id */ 1362148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos DE_NULL, /* out_te_id */ 1362248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos DE_NULL, /* out_gs_id */ 1362348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos DE_NULL, /* out_fs_id */ 1362448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos &m_po_id)) 1362548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1362648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.getLog() << tcu::TestLog::Message << "A program object was successfully built for [" 1362748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << getTestCaseString(static_cast<_test_case>(test_case)) 1362848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << "] test case, even though it was invalid." << tcu::TestLog::EndMessage; 1362948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1363048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_has_test_passed = false; 1363148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1363248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1363348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Delete any objects that may have been created */ 1363448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos deinit(); 1363548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } /* for (all test cases) */ 1363648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1363748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /** All done */ 1363848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_has_test_passed) 1363948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1364048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 1364148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1364248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else 1364348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1364448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 1364548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1364648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1364748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return STOP; 1364848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 1364948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1365048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Constructor. 1365148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1365248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param context Rendering context. 1365348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 1365448087f5f0eb08759ee763f98daf3b34becb74559Pyry HaulosNegativeTest10::NegativeTest10(deqp::Context& context) 1365548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos : TestCase(context, "function_overloading_forbidden_for_subroutines", 1365648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "Check that an overloaded function cannot be declared with subroutine and " 1365748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "a program will fail to compile or link if any shader or stage contains" 1365848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " two or more functions with the same name if the name is associated with" 1365948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " a subroutine type.") 1366048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_has_test_passed(true) 1366148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_fs_id(0) 1366248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_gs_id(0) 1366348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_po_id(0) 1366448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_tc_id(0) 1366548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_te_id(0) 1366648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_vs_id(0) 1366748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 1366848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Left blank intentionally */ 1366948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 1367048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1367148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Deinitializes any GL objects that may have been created during 1367248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * test execution. 1367348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 1367448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid NegativeTest10::deinit() 1367548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 1367648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1367748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1367848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_fs_id != 0) 1367948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1368048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteShader(m_fs_id); 1368148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1368248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_fs_id = 0; 1368348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1368448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1368548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_gs_id != 0) 1368648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1368748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteShader(m_gs_id); 1368848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1368948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_gs_id = 0; 1369048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1369148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1369248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_po_id != 0) 1369348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1369448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteProgram(m_po_id); 1369548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1369648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_po_id = 0; 1369748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1369848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1369948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_tc_id != 0) 1370048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1370148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteShader(m_tc_id); 1370248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1370348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_tc_id = 0; 1370448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1370548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1370648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_te_id != 0) 1370748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1370848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteShader(m_te_id); 1370948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1371048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_te_id = 0; 1371148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1371248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1371348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_vs_id != 0) 1371448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1371548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteShader(m_vs_id); 1371648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1371748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_vs_id = 0; 1371848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1371948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 1372048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1372148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Retrieves fragment shader that should be used for the purpose of the test. 1372248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * An overloaded version of a subroutine function is inserted if 1372348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param include_duplicate_function flag is set to true. 1372448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1372548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param include_duplicate_function As per description. 1372648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1372748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return Requested string. 1372848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 1372948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosstd::string NegativeTest10::getFragmentShader(bool include_duplicate_function) 1373048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 1373148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::stringstream result_sstream; 1373248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1373348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "#version 400\n" 1373448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1373548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "#extension GL_ARB_shader_subroutine : require\n" 1373648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1373748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine void subroutineType(inout vec4 test);\n" 1373848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1373948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine(subroutineType) void test_function(inout vec4 test)\n" 1374048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 1374148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " test = vec4(2, 3, 4, 5);\n" 1374248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 1374348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1374448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine uniform subroutineType function;\n" 1374548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "out vec4 result;\n" 1374648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n"; 1374748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1374848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (include_duplicate_function) 1374948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1375048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "void test_function(inout vec4 test)\n" 1375148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 1375248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " test = vec4(3, 4, 5, 6);\n" 1375348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 1375448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n"; 1375548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1375648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1375748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "void main()\n" 1375848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 1375948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " test_function(result);\n" 1376048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n"; 1376148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1376248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return result_sstream.str(); 1376348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 1376448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1376548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Retrieves geometry shader that should be used for the purpose of the test. 1376648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * An overloaded version of a subroutine function is inserted if 1376748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param include_duplicate_function flag is set to true. 1376848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1376948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param include_duplicate_function As per description. 1377048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1377148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return Requested string. 1377248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 1377348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosstd::string NegativeTest10::getGeometryShader(bool include_duplicate_function) 1377448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 1377548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::stringstream result_sstream; 1377648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1377748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "#version 400\n" 1377848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1377948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "#extension GL_ARB_shader_subroutine : require\n" 1378048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1378148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "layout (triangles) in;\n" 1378248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "layout (triangle_strip, max_vertices = 4) out;\n" 1378348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1378448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine void subroutineType(inout vec4 test);\n" 1378548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1378648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine(subroutineType) void test_function(inout vec4 test)\n" 1378748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 1378848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " test = vec4(2, 3, 4, 5);\n" 1378948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 1379048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1379148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine uniform subroutineType function;\n" 1379248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n"; 1379348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1379448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (include_duplicate_function) 1379548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1379648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "void test_function(inout vec4 test)\n" 1379748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 1379848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " test = vec4(3, 4, 5, 6);\n" 1379948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 1380048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n"; 1380148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1380248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1380348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "void main()\n" 1380448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 1380548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " function(gl_Position);\n" 1380648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " EmitVertex();\n" 1380748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " EndPrimitive();\n" 1380848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n"; 1380948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1381048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return result_sstream.str(); 1381148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 1381248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1381348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Retrieves tess control shader that should be used for the purpose of the test. 1381448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * An overloaded version of a subroutine function is inserted if 1381548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param include_duplicate_function flag is set to true. 1381648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1381748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param include_duplicate_function As per description. 1381848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1381948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return Requested string. 1382048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 1382148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosstd::string NegativeTest10::getTessellationControlShader(bool include_duplicate_function) 1382248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 1382348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::stringstream result_sstream; 1382448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1382548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "#version 400\n" 1382648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1382748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "#extension GL_ARB_shader_subroutine : require\n" 1382848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1382948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "layout (vertices = 4) out;\n" 1383048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1383148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine void subroutineType(inout vec4 test);\n" 1383248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1383348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine(subroutineType) void test_function(inout vec4 test)\n" 1383448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 1383548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " test = vec4(2, 3, 4, 5);\n" 1383648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 1383748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1383848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine uniform subroutineType function;\n" 1383948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n"; 1384048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1384148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (include_duplicate_function) 1384248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1384348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "void test_function(inout vec4 test)\n" 1384448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 1384548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " test = vec4(3, 4, 5, 6);\n" 1384648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 1384748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n"; 1384848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1384948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1385048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "void main()\n" 1385148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 1385248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " vec4 temp;\n" 1385348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1385448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " function(temp);\n" 1385548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1385648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " gl_out[gl_InvocationID].gl_Position = temp;\n" 1385748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " gl_TessLevelInner[0] = temp.x;\n" 1385848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " gl_TessLevelInner[1] = temp.y;\n" 1385948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " gl_TessLevelOuter[0] = temp.z;\n" 1386048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " gl_TessLevelOuter[1] = temp.w;\n" 1386148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " gl_TessLevelOuter[2] = temp.x;\n" 1386248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " gl_TessLevelOuter[3] = temp.y;\n" 1386348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n"; 1386448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1386548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return result_sstream.str(); 1386648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 1386748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1386848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Retrieves tess evaluation shader that should be used for the purpose of the test. 1386948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * An overloaded version of a subroutine function is inserted if 1387048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param include_duplicate_function flag is set to true. 1387148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1387248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param include_duplicate_function As per description. 1387348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1387448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return Requested string. 1387548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 1387648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosstd::string NegativeTest10::getTessellationEvaluationShader(bool include_duplicate_function) 1387748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 1387848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::stringstream result_sstream; 1387948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1388048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "#version 400\n" 1388148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1388248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "#extension GL_ARB_shader_subroutine : require\n" 1388348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1388448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "layout (quads) in;\n" 1388548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1388648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine void subroutineType(inout vec4 test);\n" 1388748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1388848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine(subroutineType) void test_function(inout vec4 test)\n" 1388948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 1389048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " test = vec4(2, 3, 4, 5);\n" 1389148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 1389248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1389348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine uniform subroutineType function;\n" 1389448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n"; 1389548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1389648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (include_duplicate_function) 1389748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1389848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "void test_function(inout vec4 test)\n" 1389948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 1390048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " test = vec4(3, 4, 5, 6);\n" 1390148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 1390248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n"; 1390348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1390448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1390548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "void main()\n" 1390648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 1390748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " vec4 temp;\n" 1390848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1390948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " function(temp);\n" 1391048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1391148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " gl_Position = temp;\n" 1391248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n"; 1391348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1391448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return result_sstream.str(); 1391548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 1391648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1391748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Retrieves vertex shader that should be used for the purpose of the test. 1391848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * An overloaded version of a subroutine function is inserted if 1391948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param include_duplicate_function flag is set to true. 1392048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1392148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param include_duplicate_function As per description. 1392248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1392348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return Requested string. 1392448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 1392548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosstd::string NegativeTest10::getVertexShader(bool include_duplicate_function) 1392648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 1392748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::stringstream result_sstream; 1392848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1392948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "#version 400\n" 1393048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1393148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "#extension GL_ARB_shader_subroutine : require\n" 1393248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1393348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine void subroutineType(inout vec4 test);\n" 1393448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1393548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine(subroutineType) void test_function(inout vec4 test)\n" 1393648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 1393748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " test = vec4(2, 3, 4, 5);\n" 1393848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 1393948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1394048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine uniform subroutineType function;\n" 1394148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n"; 1394248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1394348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (include_duplicate_function) 1394448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1394548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "void test_function(inout vec4 test)\n" 1394648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 1394748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " test = vec4(3, 4, 5, 6);\n" 1394848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 1394948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n"; 1395048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1395148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1395248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "void main()\n" 1395348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 1395448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " function(gl_Position);\n" 1395548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n"; 1395648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1395748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return result_sstream.str(); 1395848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 1395948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1396048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Fills m_test_cases field with test case descriptors */ 1396148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid NegativeTest10::initTestCases() 1396248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 1396348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* For each test case, only one shader stage should define a function that 1396448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * has already been defined as a subroutine. */ 1396548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (int offending_shader_stage_it = static_cast<int>(Utils::SHADER_STAGE_FIRST); 1396648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos offending_shader_stage_it != static_cast<int>(Utils::SHADER_STAGE_COUNT); ++offending_shader_stage_it) 1396748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1396848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos Utils::_shader_stage offending_shader_stage = static_cast<Utils::_shader_stage>(offending_shader_stage_it); 1396948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Form the test case descriptor */ 1397048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::stringstream name_sstream; 1397148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos _test_case test_case; 1397248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1397348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos name_sstream << "Broken shader stage:" << Utils::getShaderStageString(offending_shader_stage); 1397448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1397548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos test_case.fs_body = getFragmentShader(offending_shader_stage == Utils::SHADER_STAGE_FRAGMENT); 1397648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos test_case.gs_body = getGeometryShader(offending_shader_stage == Utils::SHADER_STAGE_GEOMETRY); 1397748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos test_case.name = name_sstream.str(); 1397848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos test_case.tc_body = 1397948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos getTessellationControlShader(offending_shader_stage == Utils::SHADER_STAGE_TESSELLATION_CONTROL); 1398048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos test_case.te_body = 1398148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos getTessellationEvaluationShader(offending_shader_stage == Utils::SHADER_STAGE_TESSELLATION_EVALUATION); 1398248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos test_case.vs_body = getVertexShader(offending_shader_stage == Utils::SHADER_STAGE_VERTEX); 1398348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1398448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_test_cases.push_back(test_case); 1398548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1398648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 1398748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1398848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Executes test iteration. 1398948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1399048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed. 1399148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos */ 1399248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulostcu::TestNode::IterateResult NegativeTest10::iterate() 1399348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 1399448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1399548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1399648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Do not execute the test if GL_ARB_shader_subroutine is not supported */ 1399748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_shader_subroutine")) 1399848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1399948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos throw tcu::NotSupportedError("GL_ARB_shader_subroutine is not supported."); 1400048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1400148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1400248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Form test cases */ 1400348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos initTestCases(); 1400448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1400548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Iterate over all test cases */ 1400648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (_test_cases_const_iterator test_case_iterator = m_test_cases.begin(); test_case_iterator != m_test_cases.end(); 1400748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos ++test_case_iterator) 1400848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1400948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const _test_case& test_case = *test_case_iterator; 1401048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1401148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Try to build the program object */ 1401248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (ShaderSubroutine::Utils::buildProgram(gl, test_case.vs_body, test_case.tc_body, test_case.te_body, 1401348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos test_case.gs_body, test_case.fs_body, DE_NULL, /* xfb_varyings */ 1401448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 0, /* n_xfb_varyings */ 1401548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos &m_vs_id, (test_case.tc_body.length() > 0) ? &m_tc_id : DE_NULL, 1401648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos (test_case.te_body.length() > 0) ? &m_te_id : DE_NULL, 1401748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos (test_case.gs_body.length() > 0) ? &m_gs_id : DE_NULL, 1401848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos (test_case.fs_body.length() > 0) ? &m_fs_id : DE_NULL, &m_po_id)) 1401948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1402048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.getLog() << tcu::TestLog::Message << "A program object was successfully built for [" 1402148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << test_case.name << "] test case, even though it was invalid." 1402248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << tcu::TestLog::EndMessage; 1402348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1402448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_has_test_passed = false; 1402548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1402648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1402748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Delete any objects that may have been created */ 1402848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos deinit(); 1402948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } /* for (all test cases) */ 1403048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1403148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /** All done */ 1403248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_has_test_passed) 1403348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1403448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 1403548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1403648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else 1403748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1403848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 1403948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1404048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1404148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return STOP; 1404248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 1404348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1404448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Constructor. 1404548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1404648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param context Rendering context. 1404748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 1404848087f5f0eb08759ee763f98daf3b34becb74559Pyry HaulosNegativeTest11::NegativeTest11(deqp::Context& context) 1404948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos : TestCase(context, "subroutine_uniforms_used_for_sampling_atomic_image_functions", 1405048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "Tries to use subroutine uniforms in invalid way in sampling, " 1405148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "atomic and image functions. Verifies that compile- or link-time " 1405248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "error occurs.") 1405348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_has_test_passed(true) 1405448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_po_id(0) 1405548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_vs_id(0) 1405648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 1405748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Left blank intentionally */ 1405848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 1405948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1406048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Deinitializes any GL objects that may have been created during 1406148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * test execution. 1406248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 1406348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid NegativeTest11::deinit() 1406448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 1406548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1406648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1406748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_po_id != 0) 1406848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1406948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteProgram(m_po_id); 1407048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1407148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_po_id = 0; 1407248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1407348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1407448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_vs_id != 0) 1407548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1407648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteShader(m_vs_id); 1407748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1407848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_vs_id = 0; 1407948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1408048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 1408148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1408248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Returns a literal corresponding to user-specified test case enum. 1408348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1408448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param test_case As per description. 1408548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1408648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return Requested string. 1408748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 1408848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosstd::string NegativeTest11::getTestCaseString(const _test_case& test_case) 1408948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 1409048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::string result = "?"; 1409148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1409248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos switch (test_case) 1409348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1409448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case TEST_CASE_INVALID_TEXTURE_SAMPLING_ATTEMPT: 1409548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = "TEST_CASE_INVALID_TEXTURE_SAMPLING_ATTEMPT"; 1409648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 1409748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case TEST_CASE_INVALID_ATOMIC_COUNTER_USAGE_ATTEMPT: 1409848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = "TEST_CASE_INVALID_ATOMIC_COUNTER_USAGE_ATTEMPT"; 1409948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 1410048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case TEST_CASE_INVALID_IMAGE_FUNCTION_USAGE_ATTEMPT: 1410148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = "TEST_CASE_INVALID_IMAGE_FUNCTION_USAGE_ATTEMPT"; 1410248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 1410348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos default: 1410448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 1410548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1410648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1410748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return result; 1410848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 1410948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1411048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Retrieves vertex shader body for user-specified test case. 1411148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1411248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param test_case As per description. 1411348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1411448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return Requested string. 1411548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 1411648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosstd::string NegativeTest11::getVertexShader(const _test_case& test_case) 1411748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 1411848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::stringstream result_sstream; 1411948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1412048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Form pre-amble */ 1412148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "#version 400\n" 1412248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1412348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "#extension GL_ARB_shader_subroutine : require\n"; 1412448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1412548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (test_case == TEST_CASE_INVALID_ATOMIC_COUNTER_USAGE_ATTEMPT) 1412648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1412748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "#extension GL_ARB_shader_atomic_counters : require\n"; 1412848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1412948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1413048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "\n" 1413148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Define a subroutine */ 1413248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine void subroutineType(inout vec4 test);\n" 1413348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1413448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine(subroutineType) void test_function(inout vec4 test)\n" 1413548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 1413648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " test += vec4(0, 1, 2, 3);\n" 1413748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 1413848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1413948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine uniform subroutineType function;\n" 1414048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1414148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1414248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Define main() body */ 1414348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void main()\n" 1414448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n"; 1414548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1414648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Implement case-specific behavior */ 1414748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos switch (test_case) 1414848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1414948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case TEST_CASE_INVALID_ATOMIC_COUNTER_USAGE_ATTEMPT: 1415048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1415148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "if (atomicCounter(function) > 2)\n" 1415248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 1415348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " gl_Position = vec4(1);\n" 1415448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n"; 1415548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1415648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 1415748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1415848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1415948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case TEST_CASE_INVALID_IMAGE_FUNCTION_USAGE_ATTEMPT: 1416048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1416148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "imageStore(function, vec2(0.0, 1.0), vec4(1.0) );\n"; 1416248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1416348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 1416448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1416548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1416648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case TEST_CASE_INVALID_TEXTURE_SAMPLING_ATTEMPT: 1416748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1416848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "gl_Position = texture(function, vec2(1.0) );\n"; 1416948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1417048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 1417148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1417248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1417348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos default: 1417448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 1417548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } /* switch (test_case) */ 1417648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1417748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Close main() body */ 1417848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "}\n"; 1417948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1418048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Done */ 1418148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return result_sstream.str(); 1418248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 1418348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1418448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Executes test iteration. 1418548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1418648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed. 1418748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos */ 1418848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulostcu::TestNode::IterateResult NegativeTest11::iterate() 1418948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 1419048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1419148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1419248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Do not execute the test if GL_ARB_shader_subroutine is not supported */ 1419348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_shader_subroutine")) 1419448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1419548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos throw tcu::NotSupportedError("GL_ARB_shader_subroutine is not supported."); 1419648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1419748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1419848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Iterate over all test cases */ 1419948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (int test_case = static_cast<int>(TEST_CASE_FIRST); test_case != static_cast<int>(TEST_CASE_COUNT); ++test_case) 1420048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1420148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (static_cast<_test_case>(test_case) == TEST_CASE_INVALID_ATOMIC_COUNTER_USAGE_ATTEMPT && 1420248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos !m_context.getContextInfo().isExtensionSupported("GL_ARB_shader_atomic_counters")) 1420348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1420448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* This iteration requires atomic counter support that this GL implementation 1420548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * is not capable of. Skip the iteration 1420648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos */ 1420748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos continue; 1420848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1420948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1421048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Try to build a program object using invalid vertex shader, specific to the 1421148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * iteration we're currently in */ 1421248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::string vs_body = getVertexShader(static_cast<_test_case>(test_case)); 1421348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1421448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (ShaderSubroutine::Utils::buildProgram(gl, vs_body, "", /* tc_body */ 1421548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "", /* te_body */ 1421648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "", /* gs_body */ 1421748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "", /* fs_body */ 1421848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos DE_NULL, /* xfb_varyings */ 1421948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 0, /* n_xfb_varyings */ 1422048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos &m_vs_id, DE_NULL, /* out_tc_id */ 1422148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos DE_NULL, /* out_te_id */ 1422248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos DE_NULL, /* out_gs_id */ 1422348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos DE_NULL, /* out_fs_id */ 1422448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos &m_po_id)) 1422548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1422648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.getLog() << tcu::TestLog::Message << "A program object was successfully built for [" 1422748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << getTestCaseString(static_cast<_test_case>(test_case)) 1422848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << "] test case, even though it was invalid." << tcu::TestLog::EndMessage; 1422948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1423048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_has_test_passed = false; 1423148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1423248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1423348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Delete any objects that may have been created */ 1423448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos deinit(); 1423548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } /* for (all test cases) */ 1423648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1423748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /** All done */ 1423848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_has_test_passed) 1423948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1424048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 1424148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1424248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else 1424348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1424448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 1424548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1424648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1424748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return STOP; 1424848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 1424948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1425048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Constructor. 1425148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1425248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param context Rendering context. 1425348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 1425448087f5f0eb08759ee763f98daf3b34becb74559Pyry HaulosNegativeTest12::NegativeTest12(deqp::Context& context) 1425548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos : TestCase(context, "subroutines_not_allowed_as_variables_constructors_and_argument_or_return_types", 1425648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "Verifies that it is not allowed to use subroutine type for " 1425748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "local/global variables, constructors or argument/return type.") 1425848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_has_test_passed(true) 1425948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_po_id(0) 1426048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_vs_id(0) 1426148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 1426248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Left blank intentionally */ 1426348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 1426448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1426548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Deinitializes any GL objects that may have been created during 1426648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * test execution. 1426748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 1426848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid NegativeTest12::deinit() 1426948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 1427048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1427148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1427248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_po_id != 0) 1427348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1427448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteProgram(m_po_id); 1427548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1427648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_po_id = 0; 1427748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1427848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1427948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_vs_id != 0) 1428048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1428148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteShader(m_vs_id); 1428248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1428348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_vs_id = 0; 1428448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1428548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 1428648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1428748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Returns a literal corresponding to user-specified test case enum. 1428848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1428948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param test_case As per description. 1429048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1429148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return Requested string. 1429248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 1429348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosstd::string NegativeTest12::getTestCaseString(const _test_case& test_case) 1429448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 1429548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::string result = "?"; 1429648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1429748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos switch (test_case) 1429848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1429948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case TEST_CASE_INVALID_LOCAL_SUBROUTINE_VARIABLE: 1430048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = "TEST_CASE_INVALID_LOCAL_SUBROUTINE_VARIABLE"; 1430148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 1430248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case TEST_CASE_INVALID_GLOBAL_SUBROUTINE_VARIABLE: 1430348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = "TEST_CASE_INVALID_GLOBAL_SUBROUTINE_VARIABLE"; 1430448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 1430548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case TEST_CASE_SUBROUTINE_USED_AS_CONSTRUCTOR: 1430648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = "TEST_CASE_SUBROUTINE_USED_AS_CONSTRUCTOR"; 1430748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 1430848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case TEST_CASE_SUBROUTINE_USED_AS_CONSTRUCTOR_ARGUMENT: 1430948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = "TEST_CASE_SUBROUTINE_USED_AS_CONSTRUCTOR_ARGUMENT"; 1431048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 1431148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case TEST_CASE_SUBROUTINE_USED_AS_CONSTRUCTOR_RETURN_TYPE: 1431248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result = "TEST_CASE_SUBROUTINE_USED_AS_CONSTRUCTOR_RETURN_TYPE"; 1431348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 1431448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos default: 1431548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 1431648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1431748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1431848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return result; 1431948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 1432048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1432148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Retrieves vertex shader body for user-specified test case. 1432248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1432348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param test_case As per description. 1432448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1432548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return Requested string. 1432648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 1432748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosstd::string NegativeTest12::getVertexShader(const _test_case& test_case) 1432848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 1432948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::stringstream result_sstream; 1433048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1433148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Form pre-amble */ 1433248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "#version 400\n" 1433348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1433448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "#extension GL_ARB_shader_subroutine : require\n" 1433548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1433648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Define a subroutine */ 1433748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine void subroutineType(inout vec4 test);\n" 1433848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1433948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine(subroutineType) void test_function(inout vec4 test)\n" 1434048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 1434148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " test += vec4(0, 1, 2, 3);\n" 1434248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 1434348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1434448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "subroutine uniform subroutineType function;\n" 1434548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n"; 1434648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1434748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Include case-specific implementation */ 1434848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos switch (test_case) 1434948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1435048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case TEST_CASE_INVALID_LOCAL_SUBROUTINE_VARIABLE: 1435148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1435248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "void main()\n" 1435348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 1435448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " subroutine subroutineType function2;\n" 1435548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " vec4 result;\n" 1435648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1435748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " function2(result);\n" 1435848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " gl_Position = result;\n" 1435948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n"; 1436048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1436148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 1436248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1436348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1436448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case TEST_CASE_INVALID_GLOBAL_SUBROUTINE_VARIABLE: 1436548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1436648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "subroutine subroutineType function2;\n" 1436748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1436848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void main()\n" 1436948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 1437048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " vec4 result;\n" 1437148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1437248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " function2(result);\n" 1437348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " gl_Position = result;\n" 1437448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n"; 1437548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1437648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 1437748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1437848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1437948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case TEST_CASE_SUBROUTINE_USED_AS_CONSTRUCTOR: 1438048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1438148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "void main()\n" 1438248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 1438348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " subroutineType(function);\n" 1438448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n"; 1438548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1438648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 1438748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1438848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1438948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case TEST_CASE_SUBROUTINE_USED_AS_CONSTRUCTOR_ARGUMENT: 1439048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1439148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "vec4 test_function(subroutineType argument)\n" 1439248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 1439348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " vec4 result = vec4(1, 2, 3, 4);\n" 1439448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1439548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " argument(result);\n" 1439648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1439748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " return result;\n" 1439848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 1439948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1440048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void main()\n" 1440148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 1440248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " test_function(function);\n" 1440348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n"; 1440448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1440548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 1440648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1440748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1440848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos case TEST_CASE_SUBROUTINE_USED_AS_CONSTRUCTOR_RETURN_TYPE: 1440948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1441048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos result_sstream << "subroutineType test_function()\n" 1441148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 1441248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " return function;\n" 1441348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n" 1441448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 1441548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void main()\n" 1441648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 1441748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " test_function()(gl_Position);\n" 1441848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n"; 1441948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1442048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 1442148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1442248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1442348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos default: 1442448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos break; 1442548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } /* switch (test_case) */ 1442648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1442748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Done */ 1442848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return result_sstream.str(); 1442948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 1443048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1443148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Executes test iteration. 1443248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1443348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed. 1443448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos */ 1443548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulostcu::TestNode::IterateResult NegativeTest12::iterate() 1443648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 1443748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1443848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1443948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Do not execute the test if GL_ARB_shader_subroutine is not supported */ 1444048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_shader_subroutine")) 1444148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1444248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos throw tcu::NotSupportedError("GL_ARB_shader_subroutine is not supported."); 1444348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1444448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1444548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Iterate over all test cases */ 1444648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (int test_case = static_cast<int>(TEST_CASE_FIRST); test_case != static_cast<int>(TEST_CASE_COUNT); ++test_case) 1444748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1444848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Try to build a program object using invalid vertex shader, specific to the 1444948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * iteration we're currently in */ 1445048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos std::string vs_body = getVertexShader(static_cast<_test_case>(test_case)); 1445148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1445248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (ShaderSubroutine::Utils::buildProgram(gl, vs_body, "", /* tc_body */ 1445348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "", /* te_body */ 1445448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "", /* gs_body */ 1445548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "", /* fs_body */ 1445648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos DE_NULL, /* xfb_varyings */ 1445748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 0, /* n_xfb_varyings */ 1445848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos &m_vs_id, DE_NULL, /* out_tc_id */ 1445948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos DE_NULL, /* out_te_id */ 1446048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos DE_NULL, /* out_gs_id */ 1446148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos DE_NULL, /* out_fs_id */ 1446248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos &m_po_id)) 1446348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1446448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.getLog() << tcu::TestLog::Message << "A program object was successfully built for [" 1446548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << getTestCaseString(static_cast<_test_case>(test_case)) 1446648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << "] test case, even though it was invalid." << tcu::TestLog::EndMessage; 1446748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1446848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_has_test_passed = false; 1446948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1447048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1447148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Delete any objects that may have been created */ 1447248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos deinit(); 1447348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } /* for (all test cases) */ 1447448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1447548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /** All done */ 1447648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_has_test_passed) 1447748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1447848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 1447948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1448048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos else 1448148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 1448248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 1448348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 1448448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1448548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return STOP; 1448648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 1448748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1448848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} /* ShaderSubroutine */ 1448948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1449048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Constructor. 1449148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1449248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param context Rendering context. 1449348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 1449448087f5f0eb08759ee763f98daf3b34becb74559Pyry HaulosShaderSubroutineTests::ShaderSubroutineTests(deqp::Context& context) 1449548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos : TestCaseGroup(context, "shader_subroutine", "Verifies \"shader_subroutine\" functionality") 1449648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 1449748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Left blank on purpose */ 1449848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 1449948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1450048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Initializes a texture_storage_multisample test group. 1450148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1450248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 1450348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid ShaderSubroutineTests::init(void) 1450448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 1450548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos addChild(new ShaderSubroutine::APITest1(m_context)); 1450648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos addChild(new ShaderSubroutine::APITest2(m_context)); 1450748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos addChild(new ShaderSubroutine::FunctionalTest1_2(m_context)); 1450848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos addChild(new ShaderSubroutine::FunctionalTest3_4(m_context)); 1450948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos addChild(new ShaderSubroutine::FunctionalTest5(m_context)); 1451048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos addChild(new ShaderSubroutine::FunctionalTest6(m_context)); 1451148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos addChild(new ShaderSubroutine::FunctionalTest7_8(m_context)); 1451248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos addChild(new ShaderSubroutine::FunctionalTest9(m_context)); 1451348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos addChild(new ShaderSubroutine::FunctionalTest10(m_context)); 1451448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos addChild(new ShaderSubroutine::FunctionalTest11(m_context)); 1451548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos addChild(new ShaderSubroutine::FunctionalTest12(m_context)); 1451648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos addChild(new ShaderSubroutine::FunctionalTest13(m_context)); 1451748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos addChild(new ShaderSubroutine::FunctionalTest14_15(m_context)); 1451848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos addChild(new ShaderSubroutine::FunctionalTest16(m_context)); 1451948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos addChild(new ShaderSubroutine::FunctionalTest17(m_context)); 1452048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos addChild(new ShaderSubroutine::FunctionalTest18_19(m_context)); 1452148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos addChild(new ShaderSubroutine::FunctionalTest20_21(m_context)); 1452248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos addChild(new ShaderSubroutine::NegativeTest1(m_context)); 1452348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos addChild(new ShaderSubroutine::NegativeTest2(m_context)); 1452448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos addChild(new ShaderSubroutine::NegativeTest3(m_context)); 1452548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos addChild(new ShaderSubroutine::NegativeTest4(m_context)); 1452648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos addChild(new ShaderSubroutine::NegativeTest5(m_context)); 1452748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos addChild(new ShaderSubroutine::NegativeTest6(m_context)); 1452848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos addChild(new ShaderSubroutine::NegativeTest7(m_context)); 1452948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos addChild(new ShaderSubroutine::NegativeTest8(m_context)); 1453048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos addChild(new ShaderSubroutine::NegativeTest9(m_context)); 1453148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos addChild(new ShaderSubroutine::NegativeTest10(m_context)); 1453248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos addChild(new ShaderSubroutine::NegativeTest11(m_context)); 1453348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos addChild(new ShaderSubroutine::NegativeTest12(m_context)); 1453448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 1453548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 1453648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} /* glcts namespace */ 14537