1e5c31af7Sopenharmony_ci/*------------------------------------------------------------------------- 2e5c31af7Sopenharmony_ci * drawElements Quality Program OpenGL ES Utilities 3e5c31af7Sopenharmony_ci * ------------------------------------------------ 4e5c31af7Sopenharmony_ci * 5e5c31af7Sopenharmony_ci * Copyright 2014 The Android Open Source Project 6e5c31af7Sopenharmony_ci * 7e5c31af7Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 8e5c31af7Sopenharmony_ci * you may not use this file except in compliance with the License. 9e5c31af7Sopenharmony_ci * You may obtain a copy of the License at 10e5c31af7Sopenharmony_ci * 11e5c31af7Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 12e5c31af7Sopenharmony_ci * 13e5c31af7Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 14e5c31af7Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 15e5c31af7Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16e5c31af7Sopenharmony_ci * See the License for the specific language governing permissions and 17e5c31af7Sopenharmony_ci * limitations under the License. 18e5c31af7Sopenharmony_ci * 19e5c31af7Sopenharmony_ci *//*! 20e5c31af7Sopenharmony_ci * \file 21e5c31af7Sopenharmony_ci * \brief Wrapper for GL program object. 22e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 23e5c31af7Sopenharmony_ci 24e5c31af7Sopenharmony_ci#include "gluShaderProgram.hpp" 25e5c31af7Sopenharmony_ci#include "gluRenderContext.hpp" 26e5c31af7Sopenharmony_ci#include "glwFunctions.hpp" 27e5c31af7Sopenharmony_ci#include "glwEnums.hpp" 28e5c31af7Sopenharmony_ci#include "tcuTestLog.hpp" 29e5c31af7Sopenharmony_ci#include "deClock.h" 30e5c31af7Sopenharmony_ci 31e5c31af7Sopenharmony_ci#include <cstring> 32e5c31af7Sopenharmony_ci 33e5c31af7Sopenharmony_ciusing std::string; 34e5c31af7Sopenharmony_ci 35e5c31af7Sopenharmony_cinamespace glu 36e5c31af7Sopenharmony_ci{ 37e5c31af7Sopenharmony_ci 38e5c31af7Sopenharmony_ci// Shader 39e5c31af7Sopenharmony_ci 40e5c31af7Sopenharmony_ciShader::Shader (const RenderContext& renderCtx, ShaderType shaderType) 41e5c31af7Sopenharmony_ci : m_gl (renderCtx.getFunctions()) 42e5c31af7Sopenharmony_ci , m_shader (0) 43e5c31af7Sopenharmony_ci{ 44e5c31af7Sopenharmony_ci m_info.type = shaderType; 45e5c31af7Sopenharmony_ci m_shader = m_gl.createShader(getGLShaderType(shaderType)); 46e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(m_gl.getError(), "glCreateShader()"); 47e5c31af7Sopenharmony_ci TCU_CHECK(m_shader); 48e5c31af7Sopenharmony_ci} 49e5c31af7Sopenharmony_ci 50e5c31af7Sopenharmony_ciShader::Shader (const glw::Functions& gl, ShaderType shaderType) 51e5c31af7Sopenharmony_ci : m_gl (gl) 52e5c31af7Sopenharmony_ci , m_shader (0) 53e5c31af7Sopenharmony_ci{ 54e5c31af7Sopenharmony_ci m_info.type = shaderType; 55e5c31af7Sopenharmony_ci m_shader = m_gl.createShader(getGLShaderType(shaderType)); 56e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(m_gl.getError(), "glCreateShader()"); 57e5c31af7Sopenharmony_ci TCU_CHECK(m_shader); 58e5c31af7Sopenharmony_ci} 59e5c31af7Sopenharmony_ci 60e5c31af7Sopenharmony_ciShader::~Shader (void) 61e5c31af7Sopenharmony_ci{ 62e5c31af7Sopenharmony_ci m_gl.deleteShader(m_shader); 63e5c31af7Sopenharmony_ci} 64e5c31af7Sopenharmony_ci 65e5c31af7Sopenharmony_civoid Shader::setSources (int numSourceStrings, const char* const* sourceStrings, const int* lengths) 66e5c31af7Sopenharmony_ci{ 67e5c31af7Sopenharmony_ci m_gl.shaderSource(m_shader, numSourceStrings, sourceStrings, lengths); 68e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(m_gl.getError(), "glShaderSource()"); 69e5c31af7Sopenharmony_ci 70e5c31af7Sopenharmony_ci m_info.source.clear(); 71e5c31af7Sopenharmony_ci for (int ndx = 0; ndx < numSourceStrings; ndx++) 72e5c31af7Sopenharmony_ci { 73e5c31af7Sopenharmony_ci const size_t length = lengths && lengths[ndx] >= 0 ? lengths[ndx] : strlen(sourceStrings[ndx]); 74e5c31af7Sopenharmony_ci m_info.source += std::string(sourceStrings[ndx], length); 75e5c31af7Sopenharmony_ci } 76e5c31af7Sopenharmony_ci} 77e5c31af7Sopenharmony_ci 78e5c31af7Sopenharmony_civoid Shader::compile (void) 79e5c31af7Sopenharmony_ci{ 80e5c31af7Sopenharmony_ci m_info.compileOk = false; 81e5c31af7Sopenharmony_ci m_info.compileTimeUs = 0; 82e5c31af7Sopenharmony_ci m_info.infoLog.clear(); 83e5c31af7Sopenharmony_ci 84e5c31af7Sopenharmony_ci { 85e5c31af7Sopenharmony_ci deUint64 compileStart = deGetMicroseconds(); 86e5c31af7Sopenharmony_ci m_gl.compileShader(m_shader); 87e5c31af7Sopenharmony_ci m_info.compileTimeUs = deGetMicroseconds() - compileStart; 88e5c31af7Sopenharmony_ci } 89e5c31af7Sopenharmony_ci 90e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(m_gl.getError(), "glCompileShader()"); 91e5c31af7Sopenharmony_ci 92e5c31af7Sopenharmony_ci // Query status 93e5c31af7Sopenharmony_ci { 94e5c31af7Sopenharmony_ci int compileStatus = 0; 95e5c31af7Sopenharmony_ci 96e5c31af7Sopenharmony_ci m_gl.getShaderiv(m_shader, GL_COMPILE_STATUS, &compileStatus); 97e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(m_gl.getError(), "glGetShaderiv()"); 98e5c31af7Sopenharmony_ci 99e5c31af7Sopenharmony_ci m_info.compileOk = compileStatus != GL_FALSE; 100e5c31af7Sopenharmony_ci } 101e5c31af7Sopenharmony_ci 102e5c31af7Sopenharmony_ci // Query log 103e5c31af7Sopenharmony_ci { 104e5c31af7Sopenharmony_ci int infoLogLen = 0; 105e5c31af7Sopenharmony_ci int unusedLen; 106e5c31af7Sopenharmony_ci 107e5c31af7Sopenharmony_ci m_gl.getShaderiv(m_shader, GL_INFO_LOG_LENGTH, &infoLogLen); 108e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(m_gl.getError(), "glGetShaderiv()"); 109e5c31af7Sopenharmony_ci 110e5c31af7Sopenharmony_ci if (infoLogLen > 0) 111e5c31af7Sopenharmony_ci { 112e5c31af7Sopenharmony_ci // The INFO_LOG_LENGTH query and the buffer query implementations have 113e5c31af7Sopenharmony_ci // very commonly off-by-one errors. Try to work around these issues. 114e5c31af7Sopenharmony_ci 115e5c31af7Sopenharmony_ci // add tolerance for off-by-one in log length, buffer write, and for terminator 116e5c31af7Sopenharmony_ci std::vector<char> infoLog(infoLogLen + 3, '\0'); 117e5c31af7Sopenharmony_ci 118e5c31af7Sopenharmony_ci // claim buf size is one smaller to protect from off-by-one writing over buffer bounds 119e5c31af7Sopenharmony_ci m_gl.getShaderInfoLog(m_shader, (int)infoLog.size() - 1, &unusedLen, &infoLog[0]); 120e5c31af7Sopenharmony_ci 121e5c31af7Sopenharmony_ci if (infoLog[(int)(infoLog.size()) - 1] != '\0') 122e5c31af7Sopenharmony_ci { 123e5c31af7Sopenharmony_ci // return whole buffer if null terminator was overwritten 124e5c31af7Sopenharmony_ci m_info.infoLog = std::string(&infoLog[0], infoLog.size()); 125e5c31af7Sopenharmony_ci } 126e5c31af7Sopenharmony_ci else 127e5c31af7Sopenharmony_ci { 128e5c31af7Sopenharmony_ci // read as C string. infoLog is guaranteed to be 0-terminated 129e5c31af7Sopenharmony_ci m_info.infoLog = std::string(&infoLog[0]); 130e5c31af7Sopenharmony_ci } 131e5c31af7Sopenharmony_ci } 132e5c31af7Sopenharmony_ci } 133e5c31af7Sopenharmony_ci} 134e5c31af7Sopenharmony_ci 135e5c31af7Sopenharmony_civoid Shader::specialize (const char* entryPoint, glw::GLuint numSpecializationConstants, 136e5c31af7Sopenharmony_ci const glw::GLuint* constantIndex, const glw::GLuint* constantValue) 137e5c31af7Sopenharmony_ci{ 138e5c31af7Sopenharmony_ci m_info.compileOk = false; 139e5c31af7Sopenharmony_ci m_info.compileTimeUs = 0; 140e5c31af7Sopenharmony_ci m_info.infoLog.clear(); 141e5c31af7Sopenharmony_ci 142e5c31af7Sopenharmony_ci { 143e5c31af7Sopenharmony_ci deUint64 compileStart = deGetMicroseconds(); 144e5c31af7Sopenharmony_ci m_gl.specializeShader(m_shader, entryPoint, numSpecializationConstants, constantIndex, constantValue); 145e5c31af7Sopenharmony_ci m_info.compileTimeUs = deGetMicroseconds() - compileStart; 146e5c31af7Sopenharmony_ci } 147e5c31af7Sopenharmony_ci 148e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(m_gl.getError(), "glSpecializeShader()"); 149e5c31af7Sopenharmony_ci 150e5c31af7Sopenharmony_ci // Query status 151e5c31af7Sopenharmony_ci { 152e5c31af7Sopenharmony_ci int compileStatus = 0; 153e5c31af7Sopenharmony_ci 154e5c31af7Sopenharmony_ci m_gl.getShaderiv(m_shader, GL_COMPILE_STATUS, &compileStatus); 155e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(m_gl.getError(), "glGetShaderiv()"); 156e5c31af7Sopenharmony_ci 157e5c31af7Sopenharmony_ci m_info.compileOk = compileStatus != GL_FALSE; 158e5c31af7Sopenharmony_ci } 159e5c31af7Sopenharmony_ci 160e5c31af7Sopenharmony_ci // Query log 161e5c31af7Sopenharmony_ci { 162e5c31af7Sopenharmony_ci int infoLogLen = 0; 163e5c31af7Sopenharmony_ci int unusedLen; 164e5c31af7Sopenharmony_ci 165e5c31af7Sopenharmony_ci m_gl.getShaderiv(m_shader, GL_INFO_LOG_LENGTH, &infoLogLen); 166e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(m_gl.getError(), "glGetShaderiv()"); 167e5c31af7Sopenharmony_ci 168e5c31af7Sopenharmony_ci if (infoLogLen > 0) 169e5c31af7Sopenharmony_ci { 170e5c31af7Sopenharmony_ci // The INFO_LOG_LENGTH query and the buffer query implementations have 171e5c31af7Sopenharmony_ci // very commonly off-by-one errors. Try to work around these issues. 172e5c31af7Sopenharmony_ci 173e5c31af7Sopenharmony_ci // add tolerance for off-by-one in log length, buffer write, and for terminator 174e5c31af7Sopenharmony_ci std::vector<char> infoLog(infoLogLen + 3, '\0'); 175e5c31af7Sopenharmony_ci 176e5c31af7Sopenharmony_ci // claim buf size is one smaller to protect from off-by-one writing over buffer bounds 177e5c31af7Sopenharmony_ci m_gl.getShaderInfoLog(m_shader, (int)infoLog.size() - 1, &unusedLen, &infoLog[0]); 178e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(m_gl.getError(), "glGetShaderInfoLog()"); 179e5c31af7Sopenharmony_ci 180e5c31af7Sopenharmony_ci if (infoLog[(int)(infoLog.size()) - 1] != '\0') 181e5c31af7Sopenharmony_ci { 182e5c31af7Sopenharmony_ci // return whole buffer if null terminator was overwritten 183e5c31af7Sopenharmony_ci m_info.infoLog = std::string(&infoLog[0], infoLog.size()); 184e5c31af7Sopenharmony_ci } 185e5c31af7Sopenharmony_ci else 186e5c31af7Sopenharmony_ci { 187e5c31af7Sopenharmony_ci // read as C string. infoLog is guaranteed to be 0-terminated 188e5c31af7Sopenharmony_ci m_info.infoLog = std::string(&infoLog[0]); 189e5c31af7Sopenharmony_ci } 190e5c31af7Sopenharmony_ci } 191e5c31af7Sopenharmony_ci } 192e5c31af7Sopenharmony_ci} 193e5c31af7Sopenharmony_ci 194e5c31af7Sopenharmony_ci// Program 195e5c31af7Sopenharmony_ci 196e5c31af7Sopenharmony_cistatic bool getProgramLinkStatus (const glw::Functions& gl, deUint32 program) 197e5c31af7Sopenharmony_ci{ 198e5c31af7Sopenharmony_ci int linkStatus = 0; 199e5c31af7Sopenharmony_ci 200e5c31af7Sopenharmony_ci gl.getProgramiv(program, GL_LINK_STATUS, &linkStatus); 201e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv()"); 202e5c31af7Sopenharmony_ci return (linkStatus != GL_FALSE); 203e5c31af7Sopenharmony_ci} 204e5c31af7Sopenharmony_ci 205e5c31af7Sopenharmony_cistatic std::string getProgramInfoLog (const glw::Functions& gl, deUint32 program) 206e5c31af7Sopenharmony_ci{ 207e5c31af7Sopenharmony_ci int infoLogLen = 0; 208e5c31af7Sopenharmony_ci int unusedLen; 209e5c31af7Sopenharmony_ci 210e5c31af7Sopenharmony_ci gl.getProgramiv(program, GL_INFO_LOG_LENGTH, &infoLogLen); 211e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv()"); 212e5c31af7Sopenharmony_ci 213e5c31af7Sopenharmony_ci if (infoLogLen > 0) 214e5c31af7Sopenharmony_ci { 215e5c31af7Sopenharmony_ci // The INFO_LOG_LENGTH query and the buffer query implementations have 216e5c31af7Sopenharmony_ci // very commonly off-by-one errors. Try to work around these issues. 217e5c31af7Sopenharmony_ci 218e5c31af7Sopenharmony_ci // add tolerance for off-by-one in log length, buffer write, and for terminator 219e5c31af7Sopenharmony_ci std::vector<char> infoLog(infoLogLen + 3, '\0'); 220e5c31af7Sopenharmony_ci 221e5c31af7Sopenharmony_ci // claim buf size is one smaller to protect from off-by-one writing over buffer bounds 222e5c31af7Sopenharmony_ci gl.getProgramInfoLog(program, (int)infoLog.size() - 1, &unusedLen, &infoLog[0]); 223e5c31af7Sopenharmony_ci 224e5c31af7Sopenharmony_ci // return whole buffer if null terminator was overwritten 225e5c31af7Sopenharmony_ci if (infoLog[(int)(infoLog.size()) - 1] != '\0') 226e5c31af7Sopenharmony_ci return std::string(&infoLog[0], infoLog.size()); 227e5c31af7Sopenharmony_ci 228e5c31af7Sopenharmony_ci // read as C string. infoLog is guaranteed to be 0-terminated 229e5c31af7Sopenharmony_ci return std::string(&infoLog[0]); 230e5c31af7Sopenharmony_ci } 231e5c31af7Sopenharmony_ci return std::string(); 232e5c31af7Sopenharmony_ci} 233e5c31af7Sopenharmony_ci 234e5c31af7Sopenharmony_ciProgram::Program (const RenderContext& renderCtx) 235e5c31af7Sopenharmony_ci : m_gl (renderCtx.getFunctions()) 236e5c31af7Sopenharmony_ci , m_program (0) 237e5c31af7Sopenharmony_ci{ 238e5c31af7Sopenharmony_ci m_program = m_gl.createProgram(); 239e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(m_gl.getError(), "glCreateProgram()"); 240e5c31af7Sopenharmony_ci} 241e5c31af7Sopenharmony_ci 242e5c31af7Sopenharmony_ciProgram::Program (const glw::Functions& gl) 243e5c31af7Sopenharmony_ci : m_gl (gl) 244e5c31af7Sopenharmony_ci , m_program (0) 245e5c31af7Sopenharmony_ci{ 246e5c31af7Sopenharmony_ci m_program = m_gl.createProgram(); 247e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(m_gl.getError(), "glCreateProgram()"); 248e5c31af7Sopenharmony_ci} 249e5c31af7Sopenharmony_ci 250e5c31af7Sopenharmony_ciProgram::Program (const RenderContext& renderCtx, deUint32 program) 251e5c31af7Sopenharmony_ci : m_gl (renderCtx.getFunctions()) 252e5c31af7Sopenharmony_ci , m_program (program) 253e5c31af7Sopenharmony_ci{ 254e5c31af7Sopenharmony_ci m_info.linkOk = getProgramLinkStatus(m_gl, program); 255e5c31af7Sopenharmony_ci m_info.infoLog = getProgramInfoLog(m_gl, program); 256e5c31af7Sopenharmony_ci} 257e5c31af7Sopenharmony_ci 258e5c31af7Sopenharmony_ciProgram::~Program (void) 259e5c31af7Sopenharmony_ci{ 260e5c31af7Sopenharmony_ci m_gl.deleteProgram(m_program); 261e5c31af7Sopenharmony_ci} 262e5c31af7Sopenharmony_ci 263e5c31af7Sopenharmony_civoid Program::attachShader (deUint32 shader) 264e5c31af7Sopenharmony_ci{ 265e5c31af7Sopenharmony_ci m_gl.attachShader(m_program, shader); 266e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(m_gl.getError(), "glAttachShader()"); 267e5c31af7Sopenharmony_ci} 268e5c31af7Sopenharmony_ci 269e5c31af7Sopenharmony_civoid Program::detachShader (deUint32 shader) 270e5c31af7Sopenharmony_ci{ 271e5c31af7Sopenharmony_ci m_gl.detachShader(m_program, shader); 272e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(m_gl.getError(), "glDetachShader()"); 273e5c31af7Sopenharmony_ci} 274e5c31af7Sopenharmony_ci 275e5c31af7Sopenharmony_civoid Program::bindAttribLocation (deUint32 location, const char* name) 276e5c31af7Sopenharmony_ci{ 277e5c31af7Sopenharmony_ci m_gl.bindAttribLocation(m_program, location, name); 278e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindAttribLocation()"); 279e5c31af7Sopenharmony_ci} 280e5c31af7Sopenharmony_ci 281e5c31af7Sopenharmony_civoid Program::transformFeedbackVaryings (int count, const char* const* varyings, deUint32 bufferMode) 282e5c31af7Sopenharmony_ci{ 283e5c31af7Sopenharmony_ci m_gl.transformFeedbackVaryings(m_program, count, varyings, bufferMode); 284e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(m_gl.getError(), "glTransformFeedbackVaryings()"); 285e5c31af7Sopenharmony_ci} 286e5c31af7Sopenharmony_ci 287e5c31af7Sopenharmony_civoid Program::link (void) 288e5c31af7Sopenharmony_ci{ 289e5c31af7Sopenharmony_ci m_info.linkOk = false; 290e5c31af7Sopenharmony_ci m_info.linkTimeUs = 0; 291e5c31af7Sopenharmony_ci m_info.infoLog.clear(); 292e5c31af7Sopenharmony_ci 293e5c31af7Sopenharmony_ci { 294e5c31af7Sopenharmony_ci deUint64 linkStart = deGetMicroseconds(); 295e5c31af7Sopenharmony_ci m_gl.linkProgram(m_program); 296e5c31af7Sopenharmony_ci m_info.linkTimeUs = deGetMicroseconds() - linkStart; 297e5c31af7Sopenharmony_ci } 298e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(m_gl.getError(), "glLinkProgram()"); 299e5c31af7Sopenharmony_ci 300e5c31af7Sopenharmony_ci m_info.linkOk = getProgramLinkStatus(m_gl, m_program); 301e5c31af7Sopenharmony_ci m_info.infoLog = getProgramInfoLog(m_gl, m_program); 302e5c31af7Sopenharmony_ci} 303e5c31af7Sopenharmony_ci 304e5c31af7Sopenharmony_cibool Program::isSeparable (void) const 305e5c31af7Sopenharmony_ci{ 306e5c31af7Sopenharmony_ci int separable = GL_FALSE; 307e5c31af7Sopenharmony_ci 308e5c31af7Sopenharmony_ci m_gl.getProgramiv(m_program, GL_PROGRAM_SEPARABLE, &separable); 309e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(m_gl.getError(), "glGetProgramiv()"); 310e5c31af7Sopenharmony_ci 311e5c31af7Sopenharmony_ci return (separable != GL_FALSE); 312e5c31af7Sopenharmony_ci} 313e5c31af7Sopenharmony_ci 314e5c31af7Sopenharmony_civoid Program::setSeparable (bool separable) 315e5c31af7Sopenharmony_ci{ 316e5c31af7Sopenharmony_ci m_gl.programParameteri(m_program, GL_PROGRAM_SEPARABLE, separable); 317e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(m_gl.getError(), "glProgramParameteri()"); 318e5c31af7Sopenharmony_ci} 319e5c31af7Sopenharmony_ci 320e5c31af7Sopenharmony_ci// ProgramPipeline 321e5c31af7Sopenharmony_ci 322e5c31af7Sopenharmony_ciProgramPipeline::ProgramPipeline (const RenderContext& renderCtx) 323e5c31af7Sopenharmony_ci : m_gl (renderCtx.getFunctions()) 324e5c31af7Sopenharmony_ci , m_pipeline (0) 325e5c31af7Sopenharmony_ci{ 326e5c31af7Sopenharmony_ci m_gl.genProgramPipelines(1, &m_pipeline); 327e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(m_gl.getError(), "glGenProgramPipelines()"); 328e5c31af7Sopenharmony_ci} 329e5c31af7Sopenharmony_ci 330e5c31af7Sopenharmony_ciProgramPipeline::ProgramPipeline (const glw::Functions& gl) 331e5c31af7Sopenharmony_ci : m_gl (gl) 332e5c31af7Sopenharmony_ci , m_pipeline (0) 333e5c31af7Sopenharmony_ci{ 334e5c31af7Sopenharmony_ci m_gl.genProgramPipelines(1, &m_pipeline); 335e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(m_gl.getError(), "glGenProgramPipelines()"); 336e5c31af7Sopenharmony_ci} 337e5c31af7Sopenharmony_ci 338e5c31af7Sopenharmony_ciProgramPipeline::~ProgramPipeline (void) 339e5c31af7Sopenharmony_ci{ 340e5c31af7Sopenharmony_ci m_gl.deleteProgramPipelines(1, &m_pipeline); 341e5c31af7Sopenharmony_ci} 342e5c31af7Sopenharmony_ci 343e5c31af7Sopenharmony_civoid ProgramPipeline::useProgramStages (deUint32 stages, deUint32 program) 344e5c31af7Sopenharmony_ci{ 345e5c31af7Sopenharmony_ci m_gl.useProgramStages(m_pipeline, stages, program); 346e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(m_gl.getError(), "glUseProgramStages()"); 347e5c31af7Sopenharmony_ci} 348e5c31af7Sopenharmony_ci 349e5c31af7Sopenharmony_civoid ProgramPipeline::activeShaderProgram (deUint32 program) 350e5c31af7Sopenharmony_ci{ 351e5c31af7Sopenharmony_ci m_gl.activeShaderProgram(m_pipeline, program); 352e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(m_gl.getError(), "glActiveShaderProgram()"); 353e5c31af7Sopenharmony_ci} 354e5c31af7Sopenharmony_ci 355e5c31af7Sopenharmony_cibool ProgramPipeline::isValid (void) 356e5c31af7Sopenharmony_ci{ 357e5c31af7Sopenharmony_ci glw::GLint status = GL_FALSE; 358e5c31af7Sopenharmony_ci m_gl.validateProgramPipeline(m_pipeline); 359e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(m_gl.getError(), "glValidateProgramPipeline()"); 360e5c31af7Sopenharmony_ci 361e5c31af7Sopenharmony_ci m_gl.getProgramPipelineiv(m_pipeline, GL_VALIDATE_STATUS, &status); 362e5c31af7Sopenharmony_ci 363e5c31af7Sopenharmony_ci return (status != GL_FALSE); 364e5c31af7Sopenharmony_ci} 365e5c31af7Sopenharmony_ci 366e5c31af7Sopenharmony_ci// ShaderProgram 367e5c31af7Sopenharmony_ci 368e5c31af7Sopenharmony_ciShaderProgram::ShaderProgram (const RenderContext& renderCtx, const ProgramSources& sources) 369e5c31af7Sopenharmony_ci : m_program(renderCtx.getFunctions()) 370e5c31af7Sopenharmony_ci{ 371e5c31af7Sopenharmony_ci init(renderCtx.getFunctions(), sources); 372e5c31af7Sopenharmony_ci} 373e5c31af7Sopenharmony_ci 374e5c31af7Sopenharmony_ciShaderProgram::ShaderProgram (const RenderContext& renderCtx, const ProgramBinaries& binaries) 375e5c31af7Sopenharmony_ci : m_program(renderCtx.getFunctions()) 376e5c31af7Sopenharmony_ci{ 377e5c31af7Sopenharmony_ci init(renderCtx.getFunctions(), binaries); 378e5c31af7Sopenharmony_ci} 379e5c31af7Sopenharmony_ci 380e5c31af7Sopenharmony_ciShaderProgram::ShaderProgram (const glw::Functions& gl, const ProgramSources& sources) 381e5c31af7Sopenharmony_ci : m_program(gl) 382e5c31af7Sopenharmony_ci{ 383e5c31af7Sopenharmony_ci init(gl, sources); 384e5c31af7Sopenharmony_ci} 385e5c31af7Sopenharmony_ci 386e5c31af7Sopenharmony_ciShaderProgram::ShaderProgram (const glw::Functions& gl, const ProgramBinaries& binaries) 387e5c31af7Sopenharmony_ci : m_program(gl) 388e5c31af7Sopenharmony_ci{ 389e5c31af7Sopenharmony_ci init(gl, binaries); 390e5c31af7Sopenharmony_ci} 391e5c31af7Sopenharmony_ci 392e5c31af7Sopenharmony_civoid ShaderProgram::init (const glw::Functions& gl, const ProgramSources& sources) 393e5c31af7Sopenharmony_ci{ 394e5c31af7Sopenharmony_ci try 395e5c31af7Sopenharmony_ci { 396e5c31af7Sopenharmony_ci bool shadersOk = true; 397e5c31af7Sopenharmony_ci 398e5c31af7Sopenharmony_ci for (int shaderType = 0; shaderType < SHADERTYPE_LAST; shaderType++) 399e5c31af7Sopenharmony_ci { 400e5c31af7Sopenharmony_ci for (int shaderNdx = 0; shaderNdx < (int)sources.sources[shaderType].size(); ++shaderNdx) 401e5c31af7Sopenharmony_ci { 402e5c31af7Sopenharmony_ci const char* source = sources.sources[shaderType][shaderNdx].c_str(); 403e5c31af7Sopenharmony_ci const int length = (int)sources.sources[shaderType][shaderNdx].size(); 404e5c31af7Sopenharmony_ci 405e5c31af7Sopenharmony_ci m_shaders[shaderType].reserve(m_shaders[shaderType].size() + 1); 406e5c31af7Sopenharmony_ci 407e5c31af7Sopenharmony_ci m_shaders[shaderType].push_back(new Shader(gl, ShaderType(shaderType))); 408e5c31af7Sopenharmony_ci m_shaders[shaderType].back()->setSources(1, &source, &length); 409e5c31af7Sopenharmony_ci m_shaders[shaderType].back()->compile(); 410e5c31af7Sopenharmony_ci 411e5c31af7Sopenharmony_ci shadersOk = shadersOk && m_shaders[shaderType].back()->getCompileStatus(); 412e5c31af7Sopenharmony_ci } 413e5c31af7Sopenharmony_ci } 414e5c31af7Sopenharmony_ci 415e5c31af7Sopenharmony_ci if (shadersOk) 416e5c31af7Sopenharmony_ci { 417e5c31af7Sopenharmony_ci for (int shaderType = 0; shaderType < SHADERTYPE_LAST; shaderType++) 418e5c31af7Sopenharmony_ci for (int shaderNdx = 0; shaderNdx < (int)m_shaders[shaderType].size(); ++shaderNdx) 419e5c31af7Sopenharmony_ci m_program.attachShader(m_shaders[shaderType][shaderNdx]->getShader()); 420e5c31af7Sopenharmony_ci 421e5c31af7Sopenharmony_ci for (std::vector<AttribLocationBinding>::const_iterator binding = sources.attribLocationBindings.begin(); binding != sources.attribLocationBindings.end(); ++binding) 422e5c31af7Sopenharmony_ci m_program.bindAttribLocation(binding->location, binding->name.c_str()); 423e5c31af7Sopenharmony_ci 424e5c31af7Sopenharmony_ci DE_ASSERT((sources.transformFeedbackBufferMode == GL_NONE) == sources.transformFeedbackVaryings.empty()); 425e5c31af7Sopenharmony_ci if (sources.transformFeedbackBufferMode != GL_NONE) 426e5c31af7Sopenharmony_ci { 427e5c31af7Sopenharmony_ci std::vector<const char*> tfVaryings(sources.transformFeedbackVaryings.size()); 428e5c31af7Sopenharmony_ci for (int ndx = 0; ndx < (int)tfVaryings.size(); ndx++) 429e5c31af7Sopenharmony_ci tfVaryings[ndx] = sources.transformFeedbackVaryings[ndx].c_str(); 430e5c31af7Sopenharmony_ci 431e5c31af7Sopenharmony_ci m_program.transformFeedbackVaryings((int)tfVaryings.size(), &tfVaryings[0], sources.transformFeedbackBufferMode); 432e5c31af7Sopenharmony_ci } 433e5c31af7Sopenharmony_ci 434e5c31af7Sopenharmony_ci if (sources.separable) 435e5c31af7Sopenharmony_ci m_program.setSeparable(true); 436e5c31af7Sopenharmony_ci 437e5c31af7Sopenharmony_ci m_program.link(); 438e5c31af7Sopenharmony_ci } 439e5c31af7Sopenharmony_ci } 440e5c31af7Sopenharmony_ci catch (...) 441e5c31af7Sopenharmony_ci { 442e5c31af7Sopenharmony_ci for (int shaderType = 0; shaderType < SHADERTYPE_LAST; shaderType++) 443e5c31af7Sopenharmony_ci for (int shaderNdx = 0; shaderNdx < (int)m_shaders[shaderType].size(); ++shaderNdx) 444e5c31af7Sopenharmony_ci delete m_shaders[shaderType][shaderNdx]; 445e5c31af7Sopenharmony_ci throw; 446e5c31af7Sopenharmony_ci } 447e5c31af7Sopenharmony_ci} 448e5c31af7Sopenharmony_ci 449e5c31af7Sopenharmony_civoid ShaderProgram::init (const glw::Functions& gl, const ProgramBinaries& binaries) 450e5c31af7Sopenharmony_ci{ 451e5c31af7Sopenharmony_ci try 452e5c31af7Sopenharmony_ci { 453e5c31af7Sopenharmony_ci bool shadersOk = true; 454e5c31af7Sopenharmony_ci 455e5c31af7Sopenharmony_ci for (deUint32 binaryNdx = 0; binaryNdx < binaries.binaries.size(); ++binaryNdx) 456e5c31af7Sopenharmony_ci { 457e5c31af7Sopenharmony_ci ShaderBinary shaderBinary = binaries.binaries[binaryNdx]; 458e5c31af7Sopenharmony_ci if (!shaderBinary.binary.empty()) 459e5c31af7Sopenharmony_ci { 460e5c31af7Sopenharmony_ci const char* binary = (const char*)shaderBinary.binary.data(); 461e5c31af7Sopenharmony_ci const int length = (int)(shaderBinary.binary.size() * sizeof(deUint32)); 462e5c31af7Sopenharmony_ci 463e5c31af7Sopenharmony_ci DE_ASSERT(shaderBinary.shaderEntryPoints.size() == shaderBinary.shaderTypes.size()); 464e5c31af7Sopenharmony_ci 465e5c31af7Sopenharmony_ci std::vector<Shader*> shaders; 466e5c31af7Sopenharmony_ci for (deUint32 shaderTypeNdx = 0; shaderTypeNdx < shaderBinary.shaderTypes.size(); ++shaderTypeNdx) 467e5c31af7Sopenharmony_ci { 468e5c31af7Sopenharmony_ci ShaderType shaderType = shaderBinary.shaderTypes[shaderTypeNdx]; 469e5c31af7Sopenharmony_ci 470e5c31af7Sopenharmony_ci Shader* shader = new Shader(gl, ShaderType(shaderType)); 471e5c31af7Sopenharmony_ci 472e5c31af7Sopenharmony_ci m_shaders[shaderType].reserve(m_shaders[shaderType].size() + 1); 473e5c31af7Sopenharmony_ci m_shaders[shaderType].push_back(shader); 474e5c31af7Sopenharmony_ci shaders.push_back(shader); 475e5c31af7Sopenharmony_ci } 476e5c31af7Sopenharmony_ci 477e5c31af7Sopenharmony_ci setBinary(gl, shaders, binaries.binaryFormat, binary, length); 478e5c31af7Sopenharmony_ci 479e5c31af7Sopenharmony_ci for (deUint32 shaderNdx = 0; shaderNdx < shaders.size(); ++shaderNdx) 480e5c31af7Sopenharmony_ci { 481e5c31af7Sopenharmony_ci shaders[shaderNdx]->specialize(shaderBinary.shaderEntryPoints[shaderNdx].c_str(), 482e5c31af7Sopenharmony_ci (deUint32)shaderBinary.specializationIndices.size(), 483e5c31af7Sopenharmony_ci shaderBinary.specializationIndices.data(), 484e5c31af7Sopenharmony_ci shaderBinary.specializationValues.data()); 485e5c31af7Sopenharmony_ci 486e5c31af7Sopenharmony_ci shadersOk = shadersOk && shaders[shaderNdx]->getCompileStatus(); 487e5c31af7Sopenharmony_ci } 488e5c31af7Sopenharmony_ci } 489e5c31af7Sopenharmony_ci } 490e5c31af7Sopenharmony_ci 491e5c31af7Sopenharmony_ci if (shadersOk) 492e5c31af7Sopenharmony_ci { 493e5c31af7Sopenharmony_ci for (int shaderType = 0; shaderType < SHADERTYPE_LAST; shaderType++) 494e5c31af7Sopenharmony_ci for (int shaderNdx = 0; shaderNdx < (int)m_shaders[shaderType].size(); ++shaderNdx) 495e5c31af7Sopenharmony_ci m_program.attachShader(m_shaders[shaderType][shaderNdx]->getShader()); 496e5c31af7Sopenharmony_ci 497e5c31af7Sopenharmony_ci m_program.link(); 498e5c31af7Sopenharmony_ci } 499e5c31af7Sopenharmony_ci } 500e5c31af7Sopenharmony_ci catch (...) 501e5c31af7Sopenharmony_ci { 502e5c31af7Sopenharmony_ci for (int shaderType = 0; shaderType < SHADERTYPE_LAST; shaderType++) 503e5c31af7Sopenharmony_ci for (int shaderNdx = 0; shaderNdx < (int)m_shaders[shaderType].size(); ++shaderNdx) 504e5c31af7Sopenharmony_ci delete m_shaders[shaderType][shaderNdx]; 505e5c31af7Sopenharmony_ci throw; 506e5c31af7Sopenharmony_ci } 507e5c31af7Sopenharmony_ci} 508e5c31af7Sopenharmony_ci 509e5c31af7Sopenharmony_civoid ShaderProgram::setBinary (const glw::Functions& gl, std::vector<Shader*>& shaders, glw::GLenum binaryFormat, const void* binaryData, const int length) 510e5c31af7Sopenharmony_ci{ 511e5c31af7Sopenharmony_ci std::vector<glw::GLuint> shaderVec; 512e5c31af7Sopenharmony_ci for (deUint32 shaderNdx = 0; shaderNdx < shaders.size(); ++shaderNdx) 513e5c31af7Sopenharmony_ci shaderVec.push_back(shaders[shaderNdx]->getShader()); 514e5c31af7Sopenharmony_ci 515e5c31af7Sopenharmony_ci gl.shaderBinary((glw::GLsizei)shaderVec.size(), shaderVec.data(), binaryFormat, binaryData, length); 516e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderBinary"); 517e5c31af7Sopenharmony_ci 518e5c31af7Sopenharmony_ci for (deUint32 shaderNdx = 0; shaderNdx < shaders.size(); ++shaderNdx) 519e5c31af7Sopenharmony_ci { 520e5c31af7Sopenharmony_ci glw::GLint shaderState; 521e5c31af7Sopenharmony_ci gl.getShaderiv(shaders[shaderNdx]->getShader(), GL_SPIR_V_BINARY_ARB, &shaderState); 522e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "getShaderiv"); 523e5c31af7Sopenharmony_ci 524e5c31af7Sopenharmony_ci DE_ASSERT(shaderState == GL_TRUE); 525e5c31af7Sopenharmony_ci } 526e5c31af7Sopenharmony_ci} 527e5c31af7Sopenharmony_ci 528e5c31af7Sopenharmony_ciShaderProgram::~ShaderProgram (void) 529e5c31af7Sopenharmony_ci{ 530e5c31af7Sopenharmony_ci for (int shaderType = 0; shaderType < SHADERTYPE_LAST; shaderType++) 531e5c31af7Sopenharmony_ci for (int shaderNdx = 0; shaderNdx < (int)m_shaders[shaderType].size(); ++shaderNdx) 532e5c31af7Sopenharmony_ci delete m_shaders[shaderType][shaderNdx]; 533e5c31af7Sopenharmony_ci} 534e5c31af7Sopenharmony_ci 535e5c31af7Sopenharmony_ci// Utilities 536e5c31af7Sopenharmony_ci 537e5c31af7Sopenharmony_cideUint32 getGLShaderType (ShaderType shaderType) 538e5c31af7Sopenharmony_ci{ 539e5c31af7Sopenharmony_ci static const deUint32 s_typeMap[] = 540e5c31af7Sopenharmony_ci { 541e5c31af7Sopenharmony_ci GL_VERTEX_SHADER, 542e5c31af7Sopenharmony_ci GL_FRAGMENT_SHADER, 543e5c31af7Sopenharmony_ci GL_GEOMETRY_SHADER, 544e5c31af7Sopenharmony_ci GL_TESS_CONTROL_SHADER, 545e5c31af7Sopenharmony_ci GL_TESS_EVALUATION_SHADER, 546e5c31af7Sopenharmony_ci GL_COMPUTE_SHADER, 547e5c31af7Sopenharmony_ci 0, 548e5c31af7Sopenharmony_ci 0, 549e5c31af7Sopenharmony_ci 0, 550e5c31af7Sopenharmony_ci 0, 551e5c31af7Sopenharmony_ci 0, 552e5c31af7Sopenharmony_ci 0, 553e5c31af7Sopenharmony_ci 0, 554e5c31af7Sopenharmony_ci 0, 555e5c31af7Sopenharmony_ci }; 556e5c31af7Sopenharmony_ci DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(s_typeMap) == SHADERTYPE_LAST); 557e5c31af7Sopenharmony_ci DE_ASSERT(de::inBounds<int>(shaderType, 0, DE_LENGTH_OF_ARRAY(s_typeMap))); 558e5c31af7Sopenharmony_ci return s_typeMap[shaderType]; 559e5c31af7Sopenharmony_ci} 560e5c31af7Sopenharmony_ci 561e5c31af7Sopenharmony_cideUint32 getGLShaderTypeBit (ShaderType shaderType) 562e5c31af7Sopenharmony_ci{ 563e5c31af7Sopenharmony_ci static const deUint32 s_typebitMap[] = 564e5c31af7Sopenharmony_ci { 565e5c31af7Sopenharmony_ci GL_VERTEX_SHADER_BIT, 566e5c31af7Sopenharmony_ci GL_FRAGMENT_SHADER_BIT, 567e5c31af7Sopenharmony_ci GL_GEOMETRY_SHADER_BIT, 568e5c31af7Sopenharmony_ci GL_TESS_CONTROL_SHADER_BIT, 569e5c31af7Sopenharmony_ci GL_TESS_EVALUATION_SHADER_BIT, 570e5c31af7Sopenharmony_ci GL_COMPUTE_SHADER_BIT, 571e5c31af7Sopenharmony_ci 0, 572e5c31af7Sopenharmony_ci 0, 573e5c31af7Sopenharmony_ci 0, 574e5c31af7Sopenharmony_ci 0, 575e5c31af7Sopenharmony_ci 0, 576e5c31af7Sopenharmony_ci 0, 577e5c31af7Sopenharmony_ci 0, 578e5c31af7Sopenharmony_ci 0, 579e5c31af7Sopenharmony_ci }; 580e5c31af7Sopenharmony_ci DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(s_typebitMap) == SHADERTYPE_LAST); 581e5c31af7Sopenharmony_ci DE_ASSERT(de::inBounds<int>(shaderType, 0, DE_LENGTH_OF_ARRAY(s_typebitMap))); 582e5c31af7Sopenharmony_ci return s_typebitMap[shaderType]; 583e5c31af7Sopenharmony_ci} 584e5c31af7Sopenharmony_ci 585e5c31af7Sopenharmony_ciqpShaderType getLogShaderType (ShaderType shaderType) 586e5c31af7Sopenharmony_ci{ 587e5c31af7Sopenharmony_ci static const qpShaderType s_typeMap[] = 588e5c31af7Sopenharmony_ci { 589e5c31af7Sopenharmony_ci QP_SHADER_TYPE_VERTEX, 590e5c31af7Sopenharmony_ci QP_SHADER_TYPE_FRAGMENT, 591e5c31af7Sopenharmony_ci QP_SHADER_TYPE_GEOMETRY, 592e5c31af7Sopenharmony_ci QP_SHADER_TYPE_TESS_CONTROL, 593e5c31af7Sopenharmony_ci QP_SHADER_TYPE_TESS_EVALUATION, 594e5c31af7Sopenharmony_ci QP_SHADER_TYPE_COMPUTE, 595e5c31af7Sopenharmony_ci QP_SHADER_TYPE_RAYGEN, 596e5c31af7Sopenharmony_ci QP_SHADER_TYPE_ANY_HIT, 597e5c31af7Sopenharmony_ci QP_SHADER_TYPE_CLOSEST_HIT, 598e5c31af7Sopenharmony_ci QP_SHADER_TYPE_MISS, 599e5c31af7Sopenharmony_ci QP_SHADER_TYPE_INTERSECTION, 600e5c31af7Sopenharmony_ci QP_SHADER_TYPE_CALLABLE, 601e5c31af7Sopenharmony_ci QP_SHADER_TYPE_TASK, 602e5c31af7Sopenharmony_ci QP_SHADER_TYPE_MESH, 603e5c31af7Sopenharmony_ci }; 604e5c31af7Sopenharmony_ci DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(s_typeMap) == SHADERTYPE_LAST); 605e5c31af7Sopenharmony_ci DE_ASSERT(de::inBounds<int>(shaderType, 0, DE_LENGTH_OF_ARRAY(s_typeMap))); 606e5c31af7Sopenharmony_ci return s_typeMap[shaderType]; 607e5c31af7Sopenharmony_ci} 608e5c31af7Sopenharmony_ci 609e5c31af7Sopenharmony_citcu::TestLog& operator<< (tcu::TestLog& log, const ShaderInfo& shaderInfo) 610e5c31af7Sopenharmony_ci{ 611e5c31af7Sopenharmony_ci return log << tcu::TestLog::Shader(getLogShaderType(shaderInfo.type), shaderInfo.source, shaderInfo.compileOk, shaderInfo.infoLog); 612e5c31af7Sopenharmony_ci} 613e5c31af7Sopenharmony_ci 614e5c31af7Sopenharmony_citcu::TestLog& operator<< (tcu::TestLog& log, const Shader& shader) 615e5c31af7Sopenharmony_ci{ 616e5c31af7Sopenharmony_ci return log << tcu::TestLog::ShaderProgram(false, "Plain shader") << shader.getInfo() << tcu::TestLog::EndShaderProgram; 617e5c31af7Sopenharmony_ci} 618e5c31af7Sopenharmony_ci 619e5c31af7Sopenharmony_cistatic void logShaderProgram (tcu::TestLog& log, const ProgramInfo& programInfo, size_t numShaders, const ShaderInfo* const* shaderInfos) 620e5c31af7Sopenharmony_ci{ 621e5c31af7Sopenharmony_ci log << tcu::TestLog::ShaderProgram(programInfo.linkOk, programInfo.infoLog); 622e5c31af7Sopenharmony_ci try 623e5c31af7Sopenharmony_ci { 624e5c31af7Sopenharmony_ci for (size_t shaderNdx = 0; shaderNdx < numShaders; ++shaderNdx) 625e5c31af7Sopenharmony_ci log << *shaderInfos[shaderNdx]; 626e5c31af7Sopenharmony_ci } 627e5c31af7Sopenharmony_ci catch (...) 628e5c31af7Sopenharmony_ci { 629e5c31af7Sopenharmony_ci log << tcu::TestLog::EndShaderProgram; 630e5c31af7Sopenharmony_ci throw; 631e5c31af7Sopenharmony_ci } 632e5c31af7Sopenharmony_ci log << tcu::TestLog::EndShaderProgram; 633e5c31af7Sopenharmony_ci 634e5c31af7Sopenharmony_ci // Write statistics. 635e5c31af7Sopenharmony_ci { 636e5c31af7Sopenharmony_ci static const struct 637e5c31af7Sopenharmony_ci { 638e5c31af7Sopenharmony_ci const char* name; 639e5c31af7Sopenharmony_ci const char* description; 640e5c31af7Sopenharmony_ci } s_compileTimeDesc[] = 641e5c31af7Sopenharmony_ci { 642e5c31af7Sopenharmony_ci { "VertexCompileTime", "Vertex shader compile time" }, 643e5c31af7Sopenharmony_ci { "FragmentCompileTime", "Fragment shader compile time" }, 644e5c31af7Sopenharmony_ci { "GeometryCompileTime", "Geometry shader compile time" }, 645e5c31af7Sopenharmony_ci { "TessControlCompileTime", "Tesselation control shader compile time" }, 646e5c31af7Sopenharmony_ci { "TessEvaluationCompileTime", "Tesselation evaluation shader compile time" }, 647e5c31af7Sopenharmony_ci { "ComputeCompileTime", "Compute shader compile time" }, 648e5c31af7Sopenharmony_ci { "RaygenCompileTime", "Raygen shader compile time" }, 649e5c31af7Sopenharmony_ci { "AnyHitCompileTime", "Any hit shader compile time" }, 650e5c31af7Sopenharmony_ci { "ClosestHitCompileTime", "Closest hit shader compile time" }, 651e5c31af7Sopenharmony_ci { "MissCompileTime", "Miss shader compile time" }, 652e5c31af7Sopenharmony_ci { "IntersectionCompileTime", "Intersection shader compile time" }, 653e5c31af7Sopenharmony_ci { "CallableCompileTime", "Callable shader compile time" }, 654e5c31af7Sopenharmony_ci { "TaskCompileTime", "Task shader compile time" }, 655e5c31af7Sopenharmony_ci { "MeshCompileTime", "Mesh shader compile time" }, 656e5c31af7Sopenharmony_ci }; 657e5c31af7Sopenharmony_ci DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(s_compileTimeDesc) == SHADERTYPE_LAST); 658e5c31af7Sopenharmony_ci 659e5c31af7Sopenharmony_ci bool allShadersOk = true; 660e5c31af7Sopenharmony_ci 661e5c31af7Sopenharmony_ci for (size_t shaderNdx = 0; shaderNdx < numShaders; ++shaderNdx) 662e5c31af7Sopenharmony_ci { 663e5c31af7Sopenharmony_ci const ShaderInfo& shaderInfo = *shaderInfos[shaderNdx]; 664e5c31af7Sopenharmony_ci 665e5c31af7Sopenharmony_ci log << tcu::TestLog::Float(s_compileTimeDesc[shaderInfo.type].name, 666e5c31af7Sopenharmony_ci s_compileTimeDesc[shaderInfo.type].description, 667e5c31af7Sopenharmony_ci "ms", QP_KEY_TAG_TIME, (float)shaderInfo.compileTimeUs / 1000.0f); 668e5c31af7Sopenharmony_ci 669e5c31af7Sopenharmony_ci allShadersOk = allShadersOk && shaderInfo.compileOk; 670e5c31af7Sopenharmony_ci } 671e5c31af7Sopenharmony_ci 672e5c31af7Sopenharmony_ci if (allShadersOk) 673e5c31af7Sopenharmony_ci log << tcu::TestLog::Float("LinkTime", "Link time", "ms", QP_KEY_TAG_TIME, (float)programInfo.linkTimeUs / 1000.0f); 674e5c31af7Sopenharmony_ci } 675e5c31af7Sopenharmony_ci} 676e5c31af7Sopenharmony_ci 677e5c31af7Sopenharmony_citcu::TestLog& operator<< (tcu::TestLog& log, const ShaderProgramInfo& shaderProgramInfo) 678e5c31af7Sopenharmony_ci{ 679e5c31af7Sopenharmony_ci std::vector<const ShaderInfo*> shaderPtrs (shaderProgramInfo.shaders.size()); 680e5c31af7Sopenharmony_ci 681e5c31af7Sopenharmony_ci for (size_t ndx = 0; ndx < shaderPtrs.size(); ndx++) 682e5c31af7Sopenharmony_ci shaderPtrs[ndx] = &shaderProgramInfo.shaders[ndx]; 683e5c31af7Sopenharmony_ci 684e5c31af7Sopenharmony_ci logShaderProgram(log, shaderProgramInfo.program, shaderPtrs.size(), shaderPtrs.empty() ? DE_NULL : &shaderPtrs[0]); 685e5c31af7Sopenharmony_ci 686e5c31af7Sopenharmony_ci return log; 687e5c31af7Sopenharmony_ci} 688e5c31af7Sopenharmony_ci 689e5c31af7Sopenharmony_citcu::TestLog& operator<< (tcu::TestLog& log, const ShaderProgram& shaderProgram) 690e5c31af7Sopenharmony_ci{ 691e5c31af7Sopenharmony_ci std::vector<const ShaderInfo*> shaderPtrs; 692e5c31af7Sopenharmony_ci 693e5c31af7Sopenharmony_ci for (int shaderType = 0; shaderType < SHADERTYPE_LAST; shaderType++) 694e5c31af7Sopenharmony_ci { 695e5c31af7Sopenharmony_ci for (int shaderNdx = 0; shaderNdx < shaderProgram.getNumShaders((ShaderType)shaderType); shaderNdx++) 696e5c31af7Sopenharmony_ci shaderPtrs.push_back(&shaderProgram.getShaderInfo((ShaderType)shaderType, shaderNdx)); 697e5c31af7Sopenharmony_ci } 698e5c31af7Sopenharmony_ci 699e5c31af7Sopenharmony_ci logShaderProgram(log, shaderProgram.getProgramInfo(), shaderPtrs.size(), shaderPtrs.empty() ? DE_NULL : &shaderPtrs[0]); 700e5c31af7Sopenharmony_ci 701e5c31af7Sopenharmony_ci return log; 702e5c31af7Sopenharmony_ci} 703e5c31af7Sopenharmony_ci 704e5c31af7Sopenharmony_citcu::TestLog& operator<< (tcu::TestLog& log, const ProgramSources& sources) 705e5c31af7Sopenharmony_ci{ 706e5c31af7Sopenharmony_ci log << tcu::TestLog::ShaderProgram(false, "(Source only)"); 707e5c31af7Sopenharmony_ci 708e5c31af7Sopenharmony_ci try 709e5c31af7Sopenharmony_ci { 710e5c31af7Sopenharmony_ci for (int shaderType = 0; shaderType < SHADERTYPE_LAST; shaderType++) 711e5c31af7Sopenharmony_ci { 712e5c31af7Sopenharmony_ci for (size_t shaderNdx = 0; shaderNdx < sources.sources[shaderType].size(); shaderNdx++) 713e5c31af7Sopenharmony_ci { 714e5c31af7Sopenharmony_ci log << tcu::TestLog::Shader(getLogShaderType((ShaderType)shaderType), 715e5c31af7Sopenharmony_ci sources.sources[shaderType][shaderNdx], 716e5c31af7Sopenharmony_ci false, ""); 717e5c31af7Sopenharmony_ci } 718e5c31af7Sopenharmony_ci } 719e5c31af7Sopenharmony_ci } 720e5c31af7Sopenharmony_ci catch (...) 721e5c31af7Sopenharmony_ci { 722e5c31af7Sopenharmony_ci log << tcu::TestLog::EndShaderProgram; 723e5c31af7Sopenharmony_ci throw; 724e5c31af7Sopenharmony_ci } 725e5c31af7Sopenharmony_ci 726e5c31af7Sopenharmony_ci log << tcu::TestLog::EndShaderProgram; 727e5c31af7Sopenharmony_ci 728e5c31af7Sopenharmony_ci return log; 729e5c31af7Sopenharmony_ci} 730e5c31af7Sopenharmony_ci 731e5c31af7Sopenharmony_ci} // glu 732