Commit f611316b by Jamie Madill

Use stream operators for appending to InfoLog.

Also add a helper class to keep the previous behaviour of automatically appending a newline after every new message. BUG=angleproject:992 Change-Id: I0ff5d2846175cf19de7a6af295af24a92451456f Reviewed-on: https://chromium-review.googlesource.com/268744Tested-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent 71c3b2c7
......@@ -113,21 +113,6 @@ void InfoLog::appendSanitized(const char *message)
mStream << message << std::endl;
}
void InfoLog::append(const char *format, ...)
{
if (!format)
{
return;
}
va_list vararg;
va_start(vararg, format);
std::string tempString(FormatString(format, vararg));
va_end(vararg);
mStream << tempString << std::endl;
}
void InfoLog::reset()
{
}
......@@ -326,7 +311,7 @@ Error Program::link(const Data &data)
result = mProgram->compileProgramExecutables(mInfoLog, mFragmentShader, mVertexShader, registers);
if (result.error.isError() || !result.linkSuccess)
{
mInfoLog.append("Failed to create D3D shaders.");
mInfoLog << "Failed to create D3D shaders.";
unlink(false);
return result.error;
}
......@@ -395,7 +380,7 @@ Error Program::loadBinary(GLenum binaryFormat, const void *binary, GLsizei lengt
GLenum format = stream.readInt<GLenum>();
if (format != mProgram->getBinaryFormat())
{
mInfoLog.append("Invalid program binary format.");
mInfoLog << "Invalid program binary format.";
return Error(GL_NO_ERROR);
}
......@@ -403,7 +388,7 @@ Error Program::loadBinary(GLenum binaryFormat, const void *binary, GLsizei lengt
int minorVersion = stream.readInt<int>();
if (majorVersion != ANGLE_MAJOR_VERSION || minorVersion != ANGLE_MINOR_VERSION)
{
mInfoLog.append("Invalid program binary version.");
mInfoLog << "Invalid program binary version.";
return Error(GL_NO_ERROR);
}
......@@ -411,7 +396,7 @@ Error Program::loadBinary(GLenum binaryFormat, const void *binary, GLsizei lengt
stream.readBytes(commitString, ANGLE_COMMIT_HASH_SIZE);
if (memcmp(commitString, ANGLE_COMMIT_HASH, sizeof(unsigned char) * ANGLE_COMMIT_HASH_SIZE) != 0)
{
mInfoLog.append("Invalid program binary version.");
mInfoLog << "Invalid program binary version.";
return Error(GL_NO_ERROR);
}
......@@ -1022,7 +1007,7 @@ void Program::validate(const Caps &caps)
}
else
{
mInfoLog.append("Program has not been successfully linked.");
mInfoLog << "Program has not been successfully linked.";
}
}
......@@ -1270,7 +1255,7 @@ bool Program::linkVaryings(InfoLog &infoLog, Shader *fragmentShader, Shader *ver
// We permit unmatched, unreferenced varyings
if (!matched && input->staticUse)
{
infoLog.append("Fragment varying %s does not match any vertex varying", input->name.c_str());
infoLog << "Fragment varying " << input->name << " does not match any vertex varying";
return false;
}
}
......@@ -1287,7 +1272,7 @@ bool Program::linkValidateInterfaceBlockFields(InfoLog &infoLog, const std::stri
if (vertexUniform.isRowMajorLayout != fragmentUniform.isRowMajorLayout)
{
infoLog.append("Matrix packings for %s differ between vertex and fragment shaders", uniformName.c_str());
infoLog << "Matrix packings for " << uniformName << " differ between vertex and fragment shaders";
return false;
}
......@@ -1307,7 +1292,7 @@ bool Program::linkAttributes(const Data &data,
// TODO(jmadill): handle aliasing robustly
if (shaderAttributes.size() >= maxAttribs)
{
infoLog.append("Too many vertex attributes.");
infoLog << "Too many vertex attributes.";
return false;
}
......@@ -1328,7 +1313,8 @@ bool Program::linkAttributes(const Data &data,
if (static_cast<GLuint>(rows + location) > maxAttribs)
{
infoLog.append("Active attribute (%s) at location %d is too big to fit", attribute.name.c_str(), location);
infoLog << "Active attribute (" << attribute.name << ") at location "
<< location << " is too big to fit";
return false;
}
......@@ -1345,7 +1331,9 @@ bool Program::linkAttributes(const Data &data,
{
if (!linkedAttribute.name.empty())
{
infoLog.append("Attribute '%s' aliases attribute '%s' at location %d", attribute.name.c_str(), linkedAttribute.name.c_str(), rowLocation);
infoLog << "Attribute '" << attribute.name
<< "' aliases attribute '" << linkedAttribute.name
<< "' at location " << rowLocation;
return false;
}
}
......@@ -1372,8 +1360,7 @@ bool Program::linkAttributes(const Data &data,
if (availableIndex == -1 || static_cast<GLuint>(availableIndex + rows) > maxAttribs)
{
infoLog.append("Too many active attributes (%s)", attribute.name.c_str());
infoLog << "Too many active attributes (" << attribute.name << ")";
return false; // Fail to link
}
......@@ -1454,17 +1441,20 @@ bool Program::areMatchingInterfaceBlocks(gl::InfoLog &infoLog, const sh::Interfa
// validate blocks for the same member types
if (vertexInterfaceBlock.fields.size() != fragmentInterfaceBlock.fields.size())
{
infoLog.append("Types for interface block '%s' differ between vertex and fragment shaders", blockName);
infoLog << "Types for interface block '" << blockName
<< "' differ between vertex and fragment shaders";
return false;
}
if (vertexInterfaceBlock.arraySize != fragmentInterfaceBlock.arraySize)
{
infoLog.append("Array sizes differ for interface block '%s' between vertex and fragment shaders", blockName);
infoLog << "Array sizes differ for interface block '" << blockName
<< "' between vertex and fragment shaders";
return false;
}
if (vertexInterfaceBlock.layout != fragmentInterfaceBlock.layout || vertexInterfaceBlock.isRowMajorLayout != fragmentInterfaceBlock.isRowMajorLayout)
{
infoLog.append("Layout qualifiers differ for interface block '%s' between vertex and fragment shaders", blockName);
infoLog << "Layout qualifiers differ for interface block '" << blockName
<< "' between vertex and fragment shaders";
return false;
}
const unsigned int numBlockMembers = vertexInterfaceBlock.fields.size();
......@@ -1474,8 +1464,10 @@ bool Program::areMatchingInterfaceBlocks(gl::InfoLog &infoLog, const sh::Interfa
const sh::InterfaceBlockField &fragmentMember = fragmentInterfaceBlock.fields[blockMemberIndex];
if (vertexMember.name != fragmentMember.name)
{
infoLog.append("Name mismatch for field %d of interface block '%s': (in vertex: '%s', in fragment: '%s')",
blockMemberIndex, blockName, vertexMember.name.c_str(), fragmentMember.name.c_str());
infoLog << "Name mismatch for field " << blockMemberIndex
<< " of interface block '" << blockName
<< "': (in vertex: '" << vertexMember.name
<< "', in fragment: '" << fragmentMember.name << "')";
return false;
}
std::string memberName = "interface block '" + vertexInterfaceBlock.name + "' member '" + vertexMember.name + "'";
......@@ -1492,23 +1484,23 @@ bool Program::linkValidateVariablesBase(InfoLog &infoLog, const std::string &var
{
if (vertexVariable.type != fragmentVariable.type)
{
infoLog.append("Types for %s differ between vertex and fragment shaders", variableName.c_str());
infoLog << "Types for " << variableName << " differ between vertex and fragment shaders";
return false;
}
if (vertexVariable.arraySize != fragmentVariable.arraySize)
{
infoLog.append("Array sizes for %s differ between vertex and fragment shaders", variableName.c_str());
infoLog << "Array sizes for " << variableName << " differ between vertex and fragment shaders";
return false;
}
if (validatePrecision && vertexVariable.precision != fragmentVariable.precision)
{
infoLog.append("Precisions for %s differ between vertex and fragment shaders", variableName.c_str());
infoLog << "Precisions for " << variableName << " differ between vertex and fragment shaders";
return false;
}
if (vertexVariable.fields.size() != fragmentVariable.fields.size())
{
infoLog.append("Structure lengths for %s differ between vertex and fragment shaders", variableName.c_str());
infoLog << "Structure lengths for " << variableName << " differ between vertex and fragment shaders";
return false;
}
const unsigned int numMembers = vertexVariable.fields.size();
......@@ -1519,9 +1511,10 @@ bool Program::linkValidateVariablesBase(InfoLog &infoLog, const std::string &var
if (vertexMember.name != fragmentMember.name)
{
infoLog.append("Name mismatch for field '%d' of %s: (in vertex: '%s', in fragment: '%s')",
memberIndex, variableName.c_str(),
vertexMember.name.c_str(), fragmentMember.name.c_str());
infoLog << "Name mismatch for field '" << memberIndex
<< "' of " << variableName
<< ": (in vertex: '" << vertexMember.name
<< "', in fragment: '" << fragmentMember.name << "')";
return false;
}
......@@ -1556,7 +1549,7 @@ bool Program::linkValidateVaryings(InfoLog &infoLog, const std::string &varyingN
if (!sh::InterpolationTypesMatch(vertexVarying.interpolation, fragmentVarying.interpolation))
{
infoLog.append("Interpolation types for %s differ between vertex and fragment shaders", varyingName.c_str());
infoLog << "Interpolation types for " << varyingName << " differ between vertex and fragment shaders";
return false;
}
......@@ -1584,7 +1577,8 @@ bool Program::gatherTransformFeedbackLinkedVaryings(InfoLog &infoLog, const std:
{
if (outTransformFeedbackLinkedVaryings->at(k).name == linkedVaryings[j].name)
{
infoLog.append("Two transform feedback varyings specify the same output variable (%s).", linkedVaryings[j].name.c_str());
infoLog << "Two transform feedback varyings specify the same output variable ("
<< linkedVaryings[j].name << ").";
return false;
}
}
......@@ -1593,8 +1587,10 @@ bool Program::gatherTransformFeedbackLinkedVaryings(InfoLog &infoLog, const std:
if (transformFeedbackBufferMode == GL_SEPARATE_ATTRIBS &&
componentCount > caps.maxTransformFeedbackSeparateComponents)
{
infoLog.append("Transform feedback varying's %s components (%u) exceed the maximum separate components (%u).",
linkedVaryings[j].name.c_str(), componentCount, caps.maxTransformFeedbackSeparateComponents);
infoLog << "Transform feedback varying's " << linkedVaryings[j].name
<< " components (" << componentCount
<< ") exceed the maximum separate components ("
<< caps.maxTransformFeedbackSeparateComponents << ").";
return false;
}
......@@ -1610,10 +1606,12 @@ bool Program::gatherTransformFeedbackLinkedVaryings(InfoLog &infoLog, const std:
ASSERT(found);
}
if (transformFeedbackBufferMode == GL_INTERLEAVED_ATTRIBS && totalComponents > caps.maxTransformFeedbackInterleavedComponents)
if (transformFeedbackBufferMode == GL_INTERLEAVED_ATTRIBS &&
totalComponents > caps.maxTransformFeedbackInterleavedComponents)
{
infoLog.append("Transform feedback varying total components (%u) exceed the maximum interleaved components (%u).",
totalComponents, caps.maxTransformFeedbackInterleavedComponents);
infoLog << "Transform feedback varying total components (" << totalComponents
<< ") exceed the maximum interleaved components ("
<< caps.maxTransformFeedbackInterleavedComponents << ").";
return false;
}
......
......@@ -71,8 +71,62 @@ class InfoLog : angle::NonCopyable
void getLog(GLsizei bufSize, GLsizei *length, char *infoLog);
void appendSanitized(const char *message);
void append(const char *info, ...);
void reset();
// This helper class ensures we append a newline after writing a line.
class StreamHelper : angle::NonCopyable
{
public:
StreamHelper(StreamHelper &&rhs)
: mStream(rhs.mStream)
{
rhs.mStream = nullptr;
}
StreamHelper &operator=(StreamHelper &&rhs)
{
std::swap(mStream, rhs.mStream);
return *this;
}
~StreamHelper()
{
// Write newline when destroyed on the stack
if (mStream)
{
(*mStream) << std::endl;
}
}
template <typename T>
StreamHelper &operator<<(const T &value)
{
(*mStream) << value;
return *this;
}
private:
friend class InfoLog;
StreamHelper(std::stringstream *stream)
: mStream(stream)
{
ASSERT(stream);
}
std::stringstream *mStream;
};
template <typename T>
StreamHelper operator<<(const T &value)
{
StreamHelper helper(&mStream);
helper << value;
return helper;
}
std::string str() const { return mStream.str(); }
private:
std::stringstream mStream;
};
......
......@@ -21,10 +21,23 @@ TEST(InfoLogTest, LogLengthCountsTerminator)
{
InfoLog infoLog;
EXPECT_EQ(0u, infoLog.getLength());
infoLog.append(" ");
infoLog << " ";
// " \n\0" = 3 characters
EXPECT_EQ(3u, infoLog.getLength());
}
// Tests that newlines get appended to the info log properly.
TEST(InfoLogTest, AppendingNewline)
{
InfoLog infoLog;
infoLog << "First" << 1 << 'x';
infoLog << "Second" << 2 << 'y';
std::string expected = "First1x\nSecond2y\n";
EXPECT_EQ(expected, infoLog.str());
}
} // namespace
......@@ -262,7 +262,7 @@ int DynamicHLSL::packVaryings(InfoLog &infoLog, VaryingPacking packing, ShaderD3
}
else
{
infoLog.append("Could not pack varying %s", varying->name.c_str());
infoLog << "Could not pack varying " << varying->name;
return -1;
}
}
......@@ -287,7 +287,7 @@ int DynamicHLSL::packVaryings(InfoLog &infoLog, VaryingPacking packing, ShaderD3
{
if (!packVarying(varying, maxVaryingVectors, packing))
{
infoLog.append("Could not pack varying %s", varying->name.c_str());
infoLog << "Could not pack varying " << varying->name;
return -1;
}
......@@ -298,7 +298,9 @@ int DynamicHLSL::packVaryings(InfoLog &infoLog, VaryingPacking packing, ShaderD3
if (!found)
{
infoLog.append("Transform feedback varying %s does not exist in the vertex shader.", transformFeedbackVarying.c_str());
infoLog << "Transform feedback varying "
<< transformFeedbackVarying
<< " does not exist in the vertex shader.";
return -1;
}
}
......@@ -757,7 +759,7 @@ bool DynamicHLSL::generateShaderLinkHLSL(const gl::Data &data, InfoLog &infoLog,
if (usesFragColor && usesFragData)
{
infoLog.append("Cannot use both gl_FragColor and gl_FragData in the same fragment shader.");
infoLog << "Cannot use both gl_FragColor and gl_FragData in the same fragment shader.";
return false;
}
......@@ -780,7 +782,7 @@ bool DynamicHLSL::generateShaderLinkHLSL(const gl::Data &data, InfoLog &infoLog,
if (static_cast<GLuint>(registersNeeded) > data.caps->maxVaryingVectors)
{
infoLog.append("No varying registers left to support gl_FragCoord/gl_PointCoord");
infoLog << "No varying registers left to support gl_FragCoord/gl_PointCoord";
return false;
}
......
......@@ -268,11 +268,11 @@ gl::Error HLSLCompiler::compileToBinary(gl::InfoLog &infoLog, const std::string
return gl::Error(GL_OUT_OF_MEMORY, "HLSL compiler had an unexpected failure, result: 0x%X.", result);
}
infoLog.append("Warning: D3D shader compilation failed with %s flags.", configs[i].name.c_str());
infoLog << "Warning: D3D shader compilation failed with " << configs[i].name << " flags.";
if (i + 1 < configs.size())
{
infoLog.append(" Retrying with %s.\n", configs[i + 1].name.c_str());
infoLog << " Retrying with " << configs[i + 1].name;
}
}
}
......
......@@ -360,7 +360,9 @@ bool ProgramD3D::validateSamplers(gl::InfoLog *infoLog, const gl::Caps &caps)
{
if (infoLog)
{
infoLog->append("Sampler uniform (%d) exceeds GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS (%d)", unit, caps.maxCombinedTextureImageUnits);
(*infoLog) << "Sampler uniform (" << unit
<< ") exceeds GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS ("
<< caps.maxCombinedTextureImageUnits << ")";
}
mCachedValidateSamplersResult = false;
......@@ -373,7 +375,8 @@ bool ProgramD3D::validateSamplers(gl::InfoLog *infoLog, const gl::Caps &caps)
{
if (infoLog)
{
infoLog->append("Samplers of conflicting types refer to the same texture image unit (%d).", unit);
(*infoLog) << "Samplers of conflicting types refer to the same texture image unit ("
<< unit << ").";
}
mCachedValidateSamplersResult = false;
......@@ -397,7 +400,9 @@ bool ProgramD3D::validateSamplers(gl::InfoLog *infoLog, const gl::Caps &caps)
{
if (infoLog)
{
infoLog->append("Sampler uniform (%d) exceeds GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS (%d)", unit, caps.maxCombinedTextureImageUnits);
(*infoLog) << "Sampler uniform (" << unit
<< ") exceeds GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS ("
<< caps.maxCombinedTextureImageUnits << ")";
}
mCachedValidateSamplersResult = false;
......@@ -410,7 +415,8 @@ bool ProgramD3D::validateSamplers(gl::InfoLog *infoLog, const gl::Caps &caps)
{
if (infoLog)
{
infoLog->append("Samplers of conflicting types refer to the same texture image unit (%d).", unit);
(*infoLog) << "Samplers of conflicting types refer to the same texture image unit ("
<< unit << ").";
}
mCachedValidateSamplersResult = false;
......@@ -433,7 +439,7 @@ LinkResult ProgramD3D::load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream)
int compileFlags = stream->readInt<int>();
if (compileFlags != ANGLE_COMPILE_OPTIMIZATION_LEVEL)
{
infoLog.append("Mismatched compilation flags.");
infoLog << "Mismatched compilation flags.";
return LinkResult(false, gl::Error(GL_NO_ERROR));
}
......@@ -464,7 +470,7 @@ LinkResult ProgramD3D::load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream)
const unsigned int uniformCount = stream->readInt<unsigned int>();
if (stream->error())
{
infoLog.append("Invalid program binary.");
infoLog << "Invalid program binary.";
return LinkResult(false, gl::Error(GL_NO_ERROR));
}
......@@ -497,7 +503,7 @@ LinkResult ProgramD3D::load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream)
const unsigned int uniformIndexCount = stream->readInt<unsigned int>();
if (stream->error())
{
infoLog.append("Invalid program binary.");
infoLog << "Invalid program binary.";
return LinkResult(false, gl::Error(GL_NO_ERROR));
}
......@@ -512,7 +518,7 @@ LinkResult ProgramD3D::load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream)
unsigned int uniformBlockCount = stream->readInt<unsigned int>();
if (stream->error())
{
infoLog.append("Invalid program binary.");
infoLog << "Invalid program binary.";
return LinkResult(false, gl::Error(GL_NO_ERROR));
}
......@@ -602,7 +608,7 @@ LinkResult ProgramD3D::load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream)
if (!shaderExecutable)
{
infoLog.append("Could not create vertex shader.");
infoLog << "Could not create vertex shader.";
return LinkResult(false, gl::Error(GL_NO_ERROR));
}
......@@ -640,7 +646,7 @@ LinkResult ProgramD3D::load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream)
if (!shaderExecutable)
{
infoLog.append("Could not create pixel shader.");
infoLog << "Could not create pixel shader.";
return LinkResult(false, gl::Error(GL_NO_ERROR));
}
......@@ -666,7 +672,7 @@ LinkResult ProgramD3D::load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream)
if (!mGeometryExecutable)
{
infoLog.append("Could not create geometry shader.");
infoLog << "Could not create geometry shader.";
return LinkResult(false, gl::Error(GL_NO_ERROR));
}
stream->skip(geometryShaderSize);
......@@ -678,7 +684,7 @@ LinkResult ProgramD3D::load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream)
GUID identifier = mRenderer->getAdapterIdentifier();
if (memcmp(&identifier, &binaryIdentifier, sizeof(GUID)) != 0)
{
infoLog.append("Invalid program binary.");
infoLog << "Invalid program binary.";
return LinkResult(false, gl::Error(GL_NO_ERROR));
}
......@@ -1188,7 +1194,7 @@ bool ProgramD3D::assignUniformBlockRegister(gl::InfoLog &infoLog, gl::UniformBlo
uniformBlock->vsRegisterIndex = registerIndex;
if (registerIndex - mRenderer->getReservedVertexUniformBuffers() >= caps.maxVertexUniformBlocks)
{
infoLog.append("Vertex shader uniform block count exceed GL_MAX_VERTEX_UNIFORM_BLOCKS (%u)", caps.maxVertexUniformBlocks);
infoLog << "Vertex shader uniform block count exceed GL_MAX_VERTEX_UNIFORM_BLOCKS (" << caps.maxVertexUniformBlocks << ")";
return false;
}
}
......@@ -1197,7 +1203,7 @@ bool ProgramD3D::assignUniformBlockRegister(gl::InfoLog &infoLog, gl::UniformBlo
uniformBlock->psRegisterIndex = registerIndex;
if (registerIndex - mRenderer->getReservedFragmentUniformBuffers() >= caps.maxFragmentUniformBlocks)
{
infoLog.append("Fragment shader uniform block count exceed GL_MAX_FRAGMENT_UNIFORM_BLOCKS (%u)", caps.maxFragmentUniformBlocks);
infoLog << "Fragment shader uniform block count exceed GL_MAX_FRAGMENT_UNIFORM_BLOCKS (" << caps.maxFragmentUniformBlocks << ")";
return false;
}
}
......@@ -1893,16 +1899,16 @@ bool ProgramD3D::indexSamplerUniform(const gl::LinkedUniform &uniform, gl::InfoL
if (!assignSamplers(uniform.vsRegisterIndex, uniform.type, uniform.arraySize, mSamplersVS,
&mUsedVertexSamplerRange))
{
infoLog.append("Vertex shader sampler count exceeds the maximum vertex texture units (%d).",
mSamplersVS.size());
infoLog << "Vertex shader sampler count exceeds the maximum vertex texture units ("
<< mSamplersVS.size() << ").";
return false;
}
unsigned int maxVertexVectors = mRenderer->getReservedVertexUniformVectors() + caps.maxVertexUniformVectors;
if (uniform.vsRegisterIndex + uniform.registerCount > maxVertexVectors)
{
infoLog.append("Vertex shader active uniforms exceed GL_MAX_VERTEX_UNIFORM_VECTORS (%u)",
caps.maxVertexUniformVectors);
infoLog << "Vertex shader active uniforms exceed GL_MAX_VERTEX_UNIFORM_VECTORS ("
<< caps.maxVertexUniformVectors << ").";
return false;
}
}
......@@ -1912,16 +1918,16 @@ bool ProgramD3D::indexSamplerUniform(const gl::LinkedUniform &uniform, gl::InfoL
if (!assignSamplers(uniform.psRegisterIndex, uniform.type, uniform.arraySize, mSamplersPS,
&mUsedPixelSamplerRange))
{
infoLog.append("Pixel shader sampler count exceeds MAX_TEXTURE_IMAGE_UNITS (%d).",
mSamplersPS.size());
infoLog << "Pixel shader sampler count exceeds MAX_TEXTURE_IMAGE_UNITS ("
<< mSamplersPS.size() << ").";
return false;
}
unsigned int maxFragmentVectors = mRenderer->getReservedFragmentUniformVectors() + caps.maxFragmentUniformVectors;
if (uniform.psRegisterIndex + uniform.registerCount > maxFragmentVectors)
{
infoLog.append("Fragment shader active uniforms exceed GL_MAX_FRAGMENT_UNIFORM_VECTORS (%u)",
caps.maxFragmentUniformVectors);
infoLog << "Fragment shader active uniforms exceed GL_MAX_FRAGMENT_UNIFORM_VECTORS ("
<< caps.maxFragmentUniformVectors << ").";
return false;
}
}
......
......@@ -113,7 +113,7 @@ LinkResult ProgramGL::link(const gl::Data &data, gl::InfoLog &infoLog,
mFunctions->deleteProgram(mProgramID);
mProgramID = 0;
infoLog.append(&buf[0]);
infoLog << &buf[0];
TRACE("\n%s", &buf[0]);
// TODO, return GL_OUT_OF_MEMORY or just fail the link? This is an unexpected case
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment