Hash :
67946766
Author :
Date :
2016-03-08T15:43:55
Improve info log length checks Extend the info log length checks to shader_utils used by tests, and treat info log with length 1 as empty, since it can only include the null terminator. At least the Intel GL driver may generate "\0" as info log in some situations, for example when compiling a user-defined function with 50000 parameters. BUG=angleproject:1323 Change-Id: I00f2965539ec235cb949c80c2a9e1d063d32fa15 Reviewed-on: https://chromium-review.googlesource.com/331461 Reviewed-by: Jamie Madill <jmadill@chromium.org> Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: Corentin Wallez <cwallez@chromium.org>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165
//
// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
#include "shader_utils.h"
#include <vector>
#include <iostream>
#include <fstream>
static std::string ReadFileToString(const std::string &source)
{
std::ifstream stream(source.c_str());
if (!stream)
{
std::cerr << "Failed to load shader file: " << source;
return "";
}
std::string result;
stream.seekg(0, std::ios::end);
result.reserve(static_cast<unsigned int>(stream.tellg()));
stream.seekg(0, std::ios::beg);
result.assign((std::istreambuf_iterator<char>(stream)), std::istreambuf_iterator<char>());
return result;
}
GLuint CompileShader(GLenum type, const std::string &source)
{
GLuint shader = glCreateShader(type);
const char *sourceArray[1] = { source.c_str() };
glShaderSource(shader, 1, sourceArray, NULL);
glCompileShader(shader);
GLint compileResult;
glGetShaderiv(shader, GL_COMPILE_STATUS, &compileResult);
if (compileResult == 0)
{
GLint infoLogLength;
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLength);
// Info log length includes the null terminator, so 1 means that the info log is an empty
// string.
if (infoLogLength > 1)
{
std::vector<GLchar> infoLog(infoLogLength);
glGetShaderInfoLog(shader, static_cast<GLsizei>(infoLog.size()), NULL, &infoLog[0]);
std::cerr << "shader compilation failed: " << &infoLog[0];
}
else
{
std::cerr << "shader compilation failed. <Empty log message>";
}
glDeleteShader(shader);
shader = 0;
}
return shader;
}
GLuint CompileShaderFromFile(GLenum type, const std::string &sourcePath)
{
std::string source = ReadFileToString(sourcePath);
if (source.empty())
{
return 0;
}
return CompileShader(type, source);
}
GLuint CompileProgramWithTransformFeedback(
const std::string &vsSource,
const std::string &fsSource,
const std::vector<std::string> &transformFeedbackVaryings,
GLenum bufferMode)
{
GLuint program = glCreateProgram();
GLuint vs = CompileShader(GL_VERTEX_SHADER, vsSource);
GLuint fs = CompileShader(GL_FRAGMENT_SHADER, fsSource);
if (vs == 0 || fs == 0)
{
glDeleteShader(fs);
glDeleteShader(vs);
glDeleteProgram(program);
return 0;
}
glAttachShader(program, vs);
glDeleteShader(vs);
glAttachShader(program, fs);
glDeleteShader(fs);
if (transformFeedbackVaryings.size() > 0)
{
std::vector<const char *> constCharTFVaryings;
for (const std::string &transformFeedbackVarying : transformFeedbackVaryings)
{
constCharTFVaryings.push_back(transformFeedbackVarying.c_str());
}
glTransformFeedbackVaryings(program, static_cast<GLsizei>(transformFeedbackVaryings.size()),
&constCharTFVaryings[0], bufferMode);
}
glLinkProgram(program);
GLint linkStatus;
glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
if (linkStatus == 0)
{
GLint infoLogLength;
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &infoLogLength);
// Info log length includes the null terminator, so 1 means that the info log is an empty
// string.
if (infoLogLength > 1)
{
std::vector<GLchar> infoLog(infoLogLength);
glGetProgramInfoLog(program, static_cast<GLsizei>(infoLog.size()), nullptr, &infoLog[0]);
std::cerr << "program link failed: " << &infoLog[0];
}
else
{
std::cerr << "program link failed. <Empty log message>";
}
glDeleteProgram(program);
return 0;
}
return program;
}
GLuint CompileProgram(const std::string &vsSource, const std::string &fsSource)
{
std::vector<std::string> emptyVector;
return CompileProgramWithTransformFeedback(vsSource, fsSource, emptyVector, GL_NONE);
}
GLuint CompileProgramFromFiles(const std::string &vsPath, const std::string &fsPath)
{
std::string vsSource = ReadFileToString(vsPath);
std::string fsSource = ReadFileToString(fsPath);
if (vsSource.empty() || fsSource.empty())
{
return 0;
}
return CompileProgram(vsSource, fsSource);
}