Commit 253b8d20 by apatrick@chromium.org

Refactor program info log out of ProgramBinary and in to Program.

Tested by setting breakpoint in esLoadProgram with the broken program. Review URL: https://codereview.appspot.com/6305114 git-svn-id: https://angleproject.googlecode.com/svn/trunk@1164 736b8ea6-26fd-11df-bfd4-992fa37f6226
parent 2979ed2c
#define MAJOR_VERSION 1 #define MAJOR_VERSION 1
#define MINOR_VERSION 0 #define MINOR_VERSION 0
#define BUILD_VERSION 0 #define BUILD_VERSION 0
#define BUILD_REVISION 1162 #define BUILD_REVISION 1164
#define STRINGIFY(x) #x #define STRINGIFY(x) #x
#define MACRO_STRINGIFY(x) STRINGIFY(x) #define MACRO_STRINGIFY(x) STRINGIFY(x)
......
...@@ -2996,7 +2996,7 @@ void Context::drawArrays(GLenum mode, GLint first, GLsizei count, GLsizei instan ...@@ -2996,7 +2996,7 @@ void Context::drawArrays(GLenum mode, GLint first, GLsizei count, GLsizei instan
applyShaders(); applyShaders();
applyTextures(); applyTextures();
if (!getCurrentProgram()->getProgramBinary()->validateSamplers(false)) if (!getCurrentProgram()->getProgramBinary()->validateSamplers(NULL))
{ {
return error(GL_INVALID_OPERATION); return error(GL_INVALID_OPERATION);
} }
......
...@@ -20,6 +20,8 @@ ...@@ -20,6 +20,8 @@
namespace gl namespace gl
{ {
const char * const g_fakepath = "C:\\fakepath";
unsigned int Program::mCurrentSerial = 1; unsigned int Program::mCurrentSerial = 1;
AttributeBindings::AttributeBindings() AttributeBindings::AttributeBindings()
...@@ -30,6 +32,112 @@ AttributeBindings::~AttributeBindings() ...@@ -30,6 +32,112 @@ AttributeBindings::~AttributeBindings()
{ {
} }
InfoLog::InfoLog() : mInfoLog(NULL)
{
}
InfoLog::~InfoLog()
{
delete[] mInfoLog;
}
int InfoLog::getLength() const
{
if (!mInfoLog)
{
return 0;
}
else
{
return strlen(mInfoLog) + 1;
}
}
void InfoLog::getLog(GLsizei bufSize, GLsizei *length, char *infoLog)
{
int index = 0;
if (bufSize > 0)
{
if (mInfoLog)
{
index = std::min(bufSize - 1, (int)strlen(mInfoLog));
memcpy(infoLog, mInfoLog, index);
}
infoLog[index] = '\0';
}
if (length)
{
*length = index;
}
}
// append a santized message to the program info log.
// The D3D compiler includes a fake file path in some of the warning or error
// messages, so lets remove all occurrences of this fake file path from the log.
void InfoLog::appendSanitized(const char *message)
{
std::string msg(message);
size_t found;
do
{
found = msg.find(g_fakepath);
if (found != std::string::npos)
{
msg.erase(found, strlen(g_fakepath));
}
}
while (found != std::string::npos);
append("%s\n", msg.c_str());
}
void InfoLog::append(const char *format, ...)
{
if (!format)
{
return;
}
char info[1024];
va_list vararg;
va_start(vararg, format);
vsnprintf(info, sizeof(info), format, vararg);
va_end(vararg);
size_t infoLength = strlen(info);
if (!mInfoLog)
{
mInfoLog = new char[infoLength + 1];
strcpy(mInfoLog, info);
}
else
{
size_t logLength = strlen(mInfoLog);
char *newLog = new char[logLength + infoLength + 1];
strcpy(newLog, mInfoLog);
strcpy(newLog + logLength, info);
delete[] mInfoLog;
mInfoLog = newLog;
}
}
void InfoLog::reset()
{
if (mInfoLog)
{
delete [] mInfoLog;
mInfoLog = NULL;
}
}
Program::Program(ResourceManager *manager, GLuint handle) : mResourceManager(manager), mHandle(handle), mSerial(issueSerial()) Program::Program(ResourceManager *manager, GLuint handle) : mResourceManager(manager), mHandle(handle), mSerial(issueSerial())
{ {
mFragmentShader = NULL; mFragmentShader = NULL;
...@@ -138,8 +246,10 @@ void Program::link() ...@@ -138,8 +246,10 @@ void Program::link()
{ {
unlink(false); unlink(false);
mInfoLog.reset();
mProgramBinary = new ProgramBinary; mProgramBinary = new ProgramBinary;
if (!mProgramBinary->link(mAttributeBindings, mFragmentShader, mVertexShader)) if (!mProgramBinary->link(mInfoLog, mAttributeBindings, mFragmentShader, mVertexShader))
{ {
unlink(false); unlink(false);
} }
...@@ -226,34 +336,12 @@ unsigned int Program::issueSerial() ...@@ -226,34 +336,12 @@ unsigned int Program::issueSerial()
int Program::getInfoLogLength() const int Program::getInfoLogLength() const
{ {
if (mProgramBinary) return mInfoLog.getLength();
{
return mProgramBinary->getInfoLogLength();
}
else
{
return 0;
}
} }
void Program::getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog) void Program::getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog)
{ {
if (mProgramBinary) return mInfoLog.getLog(bufSize, length, infoLog);
{
return mProgramBinary->getInfoLog(bufSize, length, infoLog);
}
else
{
if (bufSize > 0)
{
infoLog[0] = '\0';
}
if (length)
{
*length = 0;
}
}
} }
void Program::getAttachedShaders(GLsizei maxCount, GLsizei *count, GLuint *shaders) void Program::getAttachedShaders(GLsizei maxCount, GLsizei *count, GLuint *shaders)
...@@ -390,6 +478,20 @@ bool Program::isFlaggedForDeletion() const ...@@ -390,6 +478,20 @@ bool Program::isFlaggedForDeletion() const
return mDeleteStatus; return mDeleteStatus;
} }
void Program::validate()
{
mInfoLog.reset();
if (mProgramBinary)
{
mProgramBinary->validate(mInfoLog);
}
else
{
mInfoLog.append("Program has not been successfully linked.");
}
}
bool Program::isValidated() const bool Program::isValidated() const
{ {
if (mProgramBinary) if (mProgramBinary)
......
...@@ -23,6 +23,8 @@ class ResourceManager; ...@@ -23,6 +23,8 @@ class ResourceManager;
class FragmentShader; class FragmentShader;
class VertexShader; class VertexShader;
extern const char * const g_fakepath;
class AttributeBindings class AttributeBindings
{ {
public: public:
...@@ -36,6 +38,23 @@ class AttributeBindings ...@@ -36,6 +38,23 @@ class AttributeBindings
std::set<std::string> mAttributeBinding[MAX_VERTEX_ATTRIBS]; std::set<std::string> mAttributeBinding[MAX_VERTEX_ATTRIBS];
}; };
class InfoLog
{
public:
InfoLog();
~InfoLog();
int getLength() const;
void getLog(GLsizei bufSize, GLsizei *length, char *infoLog);
void appendSanitized(const char *message);
void append(const char *info, ...);
void reset();
private:
DISALLOW_COPY_AND_ASSIGN(InfoLog);
char *mInfoLog;
};
class Program class Program
{ {
public: public:
...@@ -71,6 +90,7 @@ class Program ...@@ -71,6 +90,7 @@ class Program
void flagForDeletion(); void flagForDeletion();
bool isFlaggedForDeletion() const; bool isFlaggedForDeletion() const;
void validate();
bool isValidated() const; bool isValidated() const;
unsigned int getSerial() const; unsigned int getSerial() const;
...@@ -98,6 +118,8 @@ class Program ...@@ -98,6 +118,8 @@ class Program
ResourceManager *mResourceManager; ResourceManager *mResourceManager;
const GLuint mHandle; const GLuint mHandle;
InfoLog mInfoLog;
}; };
} }
......
...@@ -24,8 +24,6 @@ ...@@ -24,8 +24,6 @@
namespace gl namespace gl
{ {
const char *fakepath = "C:\\fakepath";
std::string str(int i) std::string str(int i)
{ {
char buffer[20]; char buffer[20];
...@@ -66,7 +64,6 @@ ProgramBinary::ProgramBinary() ...@@ -66,7 +64,6 @@ ProgramBinary::ProgramBinary()
mConstantTablePS = NULL; mConstantTablePS = NULL;
mConstantTableVS = NULL; mConstantTableVS = NULL;
mInfoLog = NULL;
mValidated = false; mValidated = false;
for (int index = 0; index < MAX_VERTEX_ATTRIBS; index++) for (int index = 0; index < MAX_VERTEX_ATTRIBS; index++)
...@@ -122,8 +119,6 @@ ProgramBinary::~ProgramBinary() ...@@ -122,8 +119,6 @@ ProgramBinary::~ProgramBinary()
delete mUniforms.back(); delete mUniforms.back();
mUniforms.pop_back(); mUniforms.pop_back();
} }
delete[] mInfoLog;
} }
IDirect3DPixelShader9 *ProgramBinary::getPixelShader() IDirect3DPixelShader9 *ProgramBinary::getPixelShader()
...@@ -1027,7 +1022,7 @@ void ProgramBinary::applyUniforms() ...@@ -1027,7 +1022,7 @@ void ProgramBinary::applyUniforms()
} }
// Compiles the HLSL code of the attached shaders into executable binaries // Compiles the HLSL code of the attached shaders into executable binaries
ID3D10Blob *ProgramBinary::compileToBinary(const char *hlsl, const char *profile, ID3DXConstantTable **constantTable) ID3D10Blob *ProgramBinary::compileToBinary(InfoLog &infoLog, const char *hlsl, const char *profile, ID3DXConstantTable **constantTable)
{ {
if (!hlsl) if (!hlsl)
{ {
...@@ -1058,13 +1053,13 @@ ID3D10Blob *ProgramBinary::compileToBinary(const char *hlsl, const char *profile ...@@ -1058,13 +1053,13 @@ ID3D10Blob *ProgramBinary::compileToBinary(const char *hlsl, const char *profile
ID3D10Blob *binary = NULL; ID3D10Blob *binary = NULL;
ID3D10Blob *errorMessage = NULL; ID3D10Blob *errorMessage = NULL;
result = D3DCompile(hlsl, strlen(hlsl), fakepath, NULL, NULL, "main", profile, flags, 0, &binary, &errorMessage); result = D3DCompile(hlsl, strlen(hlsl), g_fakepath, NULL, NULL, "main", profile, flags, 0, &binary, &errorMessage);
if (errorMessage) if (errorMessage)
{ {
const char *message = (const char*)errorMessage->GetBufferPointer(); const char *message = (const char*)errorMessage->GetBufferPointer();
appendToInfoLogSanitized(message); infoLog.appendSanitized(message);
TRACE("\n%s", hlsl); TRACE("\n%s", hlsl);
TRACE("\n%s", message); TRACE("\n%s", message);
...@@ -1101,7 +1096,7 @@ ID3D10Blob *ProgramBinary::compileToBinary(const char *hlsl, const char *profile ...@@ -1101,7 +1096,7 @@ ID3D10Blob *ProgramBinary::compileToBinary(const char *hlsl, const char *profile
// Packs varyings into generic varying registers, using the algorithm from [OpenGL ES Shading Language 1.00 rev. 17] appendix A section 7 page 111 // Packs varyings into generic varying registers, using the algorithm from [OpenGL ES Shading Language 1.00 rev. 17] appendix A section 7 page 111
// Returns the number of used varying registers, or -1 if unsuccesful // Returns the number of used varying registers, or -1 if unsuccesful
int ProgramBinary::packVaryings(const Varying *packing[][4], FragmentShader *fragmentShader) int ProgramBinary::packVaryings(InfoLog &infoLog, const Varying *packing[][4], FragmentShader *fragmentShader)
{ {
Context *context = getContext(); Context *context = getContext();
const int maxVaryingVectors = context->getMaximumVaryingVectors(); const int maxVaryingVectors = context->getMaximumVaryingVectors();
...@@ -1229,7 +1224,7 @@ int ProgramBinary::packVaryings(const Varying *packing[][4], FragmentShader *fra ...@@ -1229,7 +1224,7 @@ int ProgramBinary::packVaryings(const Varying *packing[][4], FragmentShader *fra
if (!success) if (!success)
{ {
appendToInfoLog("Could not pack varying %s", varying->name.c_str()); infoLog.append("Could not pack varying %s", varying->name.c_str());
return -1; return -1;
} }
...@@ -1249,7 +1244,7 @@ int ProgramBinary::packVaryings(const Varying *packing[][4], FragmentShader *fra ...@@ -1249,7 +1244,7 @@ int ProgramBinary::packVaryings(const Varying *packing[][4], FragmentShader *fra
return registers; return registers;
} }
bool ProgramBinary::linkVaryings(std::string& pixelHLSL, std::string& vertexHLSL, FragmentShader *fragmentShader, VertexShader *vertexShader) bool ProgramBinary::linkVaryings(InfoLog &infoLog, std::string& pixelHLSL, std::string& vertexHLSL, FragmentShader *fragmentShader, VertexShader *vertexShader)
{ {
if (pixelHLSL.empty() || vertexHLSL.empty()) if (pixelHLSL.empty() || vertexHLSL.empty())
{ {
...@@ -1271,7 +1266,7 @@ bool ProgramBinary::linkVaryings(std::string& pixelHLSL, std::string& vertexHLSL ...@@ -1271,7 +1266,7 @@ bool ProgramBinary::linkVaryings(std::string& pixelHLSL, std::string& vertexHLSL
// Map the varyings to the register file // Map the varyings to the register file
const Varying *packing[MAX_VARYING_VECTORS_SM3][4] = {NULL}; const Varying *packing[MAX_VARYING_VECTORS_SM3][4] = {NULL};
int registers = packVaryings(packing, fragmentShader); int registers = packVaryings(infoLog, packing, fragmentShader);
if (registers < 0) if (registers < 0)
{ {
...@@ -1285,7 +1280,7 @@ bool ProgramBinary::linkVaryings(std::string& pixelHLSL, std::string& vertexHLSL ...@@ -1285,7 +1280,7 @@ bool ProgramBinary::linkVaryings(std::string& pixelHLSL, std::string& vertexHLSL
if (registers == maxVaryingVectors && fragmentShader->mUsesFragCoord) if (registers == maxVaryingVectors && fragmentShader->mUsesFragCoord)
{ {
appendToInfoLog("No varying registers left to support gl_FragCoord"); infoLog.append("No varying registers left to support gl_FragCoord");
return false; return false;
} }
...@@ -1300,7 +1295,7 @@ bool ProgramBinary::linkVaryings(std::string& pixelHLSL, std::string& vertexHLSL ...@@ -1300,7 +1295,7 @@ bool ProgramBinary::linkVaryings(std::string& pixelHLSL, std::string& vertexHLSL
{ {
if (output->type != input->type || output->size != input->size) if (output->type != input->type || output->size != input->size)
{ {
appendToInfoLog("Type of vertex varying %s does not match that of the fragment varying", output->name.c_str()); infoLog.append("Type of vertex varying %s does not match that of the fragment varying", output->name.c_str());
return false; return false;
} }
...@@ -1315,7 +1310,7 @@ bool ProgramBinary::linkVaryings(std::string& pixelHLSL, std::string& vertexHLSL ...@@ -1315,7 +1310,7 @@ bool ProgramBinary::linkVaryings(std::string& pixelHLSL, std::string& vertexHLSL
if (!matched) if (!matched)
{ {
appendToInfoLog("Fragment varying %s does not match any vertex varying", input->name.c_str()); infoLog.append("Fragment varying %s does not match any vertex varying", input->name.c_str());
return false; return false;
} }
...@@ -1590,7 +1585,7 @@ bool ProgramBinary::linkVaryings(std::string& pixelHLSL, std::string& vertexHLSL ...@@ -1590,7 +1585,7 @@ bool ProgramBinary::linkVaryings(std::string& pixelHLSL, std::string& vertexHLSL
return true; return true;
} }
bool ProgramBinary::link(const AttributeBindings &attributeBindings, FragmentShader *fragmentShader, VertexShader *vertexShader) bool ProgramBinary::link(InfoLog &infoLog, const AttributeBindings &attributeBindings, FragmentShader *fragmentShader, VertexShader *vertexShader)
{ {
if (!fragmentShader || !fragmentShader->isCompiled()) if (!fragmentShader || !fragmentShader->isCompiled())
{ {
...@@ -1605,7 +1600,7 @@ bool ProgramBinary::link(const AttributeBindings &attributeBindings, FragmentSha ...@@ -1605,7 +1600,7 @@ bool ProgramBinary::link(const AttributeBindings &attributeBindings, FragmentSha
std::string pixelHLSL = fragmentShader->getHLSL(); std::string pixelHLSL = fragmentShader->getHLSL();
std::string vertexHLSL = vertexShader->getHLSL(); std::string vertexHLSL = vertexShader->getHLSL();
if (!linkVaryings(pixelHLSL, vertexHLSL, fragmentShader, vertexShader)) if (!linkVaryings(infoLog, pixelHLSL, vertexHLSL, fragmentShader, vertexShader))
{ {
return false; return false;
} }
...@@ -1614,8 +1609,8 @@ bool ProgramBinary::link(const AttributeBindings &attributeBindings, FragmentSha ...@@ -1614,8 +1609,8 @@ bool ProgramBinary::link(const AttributeBindings &attributeBindings, FragmentSha
const char *vertexProfile = context->supportsShaderModel3() ? "vs_3_0" : "vs_2_0"; const char *vertexProfile = context->supportsShaderModel3() ? "vs_3_0" : "vs_2_0";
const char *pixelProfile = context->supportsShaderModel3() ? "ps_3_0" : "ps_2_0"; const char *pixelProfile = context->supportsShaderModel3() ? "ps_3_0" : "ps_2_0";
ID3D10Blob *vertexBinary = compileToBinary(vertexHLSL.c_str(), vertexProfile, &mConstantTableVS); ID3D10Blob *vertexBinary = compileToBinary(infoLog, vertexHLSL.c_str(), vertexProfile, &mConstantTableVS);
ID3D10Blob *pixelBinary = compileToBinary(pixelHLSL.c_str(), pixelProfile, &mConstantTablePS); ID3D10Blob *pixelBinary = compileToBinary(infoLog, pixelHLSL.c_str(), pixelProfile, &mConstantTablePS);
if (vertexBinary && pixelBinary) if (vertexBinary && pixelBinary)
{ {
...@@ -1636,17 +1631,17 @@ bool ProgramBinary::link(const AttributeBindings &attributeBindings, FragmentSha ...@@ -1636,17 +1631,17 @@ bool ProgramBinary::link(const AttributeBindings &attributeBindings, FragmentSha
if (mVertexExecutable && mPixelExecutable) if (mVertexExecutable && mPixelExecutable)
{ {
if (!linkAttributes(attributeBindings, fragmentShader, vertexShader)) if (!linkAttributes(infoLog, attributeBindings, fragmentShader, vertexShader))
{ {
return false; return false;
} }
if (!linkUniforms(GL_FRAGMENT_SHADER, mConstantTablePS)) if (!linkUniforms(infoLog, GL_FRAGMENT_SHADER, mConstantTablePS))
{ {
return false; return false;
} }
if (!linkUniforms(GL_VERTEX_SHADER, mConstantTableVS)) if (!linkUniforms(infoLog, GL_VERTEX_SHADER, mConstantTableVS))
{ {
return false; return false;
} }
...@@ -1670,7 +1665,7 @@ bool ProgramBinary::link(const AttributeBindings &attributeBindings, FragmentSha ...@@ -1670,7 +1665,7 @@ bool ProgramBinary::link(const AttributeBindings &attributeBindings, FragmentSha
} }
// Determines the mapping between GL attributes and Direct3D 9 vertex stream usage indices // Determines the mapping between GL attributes and Direct3D 9 vertex stream usage indices
bool ProgramBinary::linkAttributes(const AttributeBindings &attributeBindings, FragmentShader *fragmentShader, VertexShader *vertexShader) bool ProgramBinary::linkAttributes(InfoLog &infoLog, const AttributeBindings &attributeBindings, FragmentShader *fragmentShader, VertexShader *vertexShader)
{ {
unsigned int usedLocations = 0; unsigned int usedLocations = 0;
...@@ -1692,7 +1687,7 @@ bool ProgramBinary::linkAttributes(const AttributeBindings &attributeBindings, F ...@@ -1692,7 +1687,7 @@ bool ProgramBinary::linkAttributes(const AttributeBindings &attributeBindings, F
if (rows + location > MAX_VERTEX_ATTRIBS) if (rows + location > MAX_VERTEX_ATTRIBS)
{ {
appendToInfoLog("Active attribute (%s) at location %d is too big to fit", attribute->name.c_str(), location); infoLog.append("Active attribute (%s) at location %d is too big to fit", attribute->name.c_str(), location);
return false; return false;
} }
...@@ -1716,7 +1711,7 @@ bool ProgramBinary::linkAttributes(const AttributeBindings &attributeBindings, F ...@@ -1716,7 +1711,7 @@ bool ProgramBinary::linkAttributes(const AttributeBindings &attributeBindings, F
if (availableIndex == -1 || availableIndex + rows > MAX_VERTEX_ATTRIBS) if (availableIndex == -1 || availableIndex + rows > MAX_VERTEX_ATTRIBS)
{ {
appendToInfoLog("Too many active attributes (%s)", attribute->name.c_str()); infoLog.append("Too many active attributes (%s)", attribute->name.c_str());
return false; // Fail to link return false; // Fail to link
} }
...@@ -1739,7 +1734,7 @@ bool ProgramBinary::linkAttributes(const AttributeBindings &attributeBindings, F ...@@ -1739,7 +1734,7 @@ bool ProgramBinary::linkAttributes(const AttributeBindings &attributeBindings, F
return true; return true;
} }
bool ProgramBinary::linkUniforms(GLenum shader, ID3DXConstantTable *constantTable) bool ProgramBinary::linkUniforms(InfoLog &infoLog, GLenum shader, ID3DXConstantTable *constantTable)
{ {
D3DXCONSTANTTABLE_DESC constantTableDescription; D3DXCONSTANTTABLE_DESC constantTableDescription;
...@@ -1754,7 +1749,7 @@ bool ProgramBinary::linkUniforms(GLenum shader, ID3DXConstantTable *constantTabl ...@@ -1754,7 +1749,7 @@ bool ProgramBinary::linkUniforms(GLenum shader, ID3DXConstantTable *constantTabl
HRESULT result = constantTable->GetConstantDesc(constantHandle, &constantDescription, &descriptionCount); HRESULT result = constantTable->GetConstantDesc(constantHandle, &constantDescription, &descriptionCount);
ASSERT(SUCCEEDED(result)); ASSERT(SUCCEEDED(result));
if (!defineUniform(shader, constantHandle, constantDescription)) if (!defineUniform(infoLog, shader, constantHandle, constantDescription))
{ {
return false; return false;
} }
...@@ -1765,7 +1760,7 @@ bool ProgramBinary::linkUniforms(GLenum shader, ID3DXConstantTable *constantTabl ...@@ -1765,7 +1760,7 @@ bool ProgramBinary::linkUniforms(GLenum shader, ID3DXConstantTable *constantTabl
// Adds the description of a constant found in the binary shader to the list of uniforms // Adds the description of a constant found in the binary shader to the list of uniforms
// Returns true if succesful (uniform not already defined) // Returns true if succesful (uniform not already defined)
bool ProgramBinary::defineUniform(GLenum shader, const D3DXHANDLE &constantHandle, const D3DXCONSTANT_DESC &constantDescription, std::string name) bool ProgramBinary::defineUniform(InfoLog &infoLog, GLenum shader, const D3DXHANDLE &constantHandle, const D3DXCONSTANT_DESC &constantDescription, std::string name)
{ {
if (constantDescription.RegisterSet == D3DXRS_SAMPLER) if (constantDescription.RegisterSet == D3DXRS_SAMPLER)
{ {
...@@ -1787,7 +1782,7 @@ bool ProgramBinary::defineUniform(GLenum shader, const D3DXHANDLE &constantHandl ...@@ -1787,7 +1782,7 @@ bool ProgramBinary::defineUniform(GLenum shader, const D3DXHANDLE &constantHandl
} }
else else
{ {
appendToInfoLog("Pixel shader sampler count exceeds MAX_TEXTURE_IMAGE_UNITS (%d).", MAX_TEXTURE_IMAGE_UNITS); infoLog.append("Pixel shader sampler count exceeds MAX_TEXTURE_IMAGE_UNITS (%d).", MAX_TEXTURE_IMAGE_UNITS);
return false; return false;
} }
} }
...@@ -1805,7 +1800,7 @@ bool ProgramBinary::defineUniform(GLenum shader, const D3DXHANDLE &constantHandl ...@@ -1805,7 +1800,7 @@ bool ProgramBinary::defineUniform(GLenum shader, const D3DXHANDLE &constantHandl
} }
else else
{ {
appendToInfoLog("Vertex shader sampler count exceeds MAX_VERTEX_TEXTURE_IMAGE_UNITS (%d).", getContext()->getMaximumVertexTextureImageUnits()); infoLog.append("Vertex shader sampler count exceeds MAX_VERTEX_TEXTURE_IMAGE_UNITS (%d).", getContext()->getMaximumVertexTextureImageUnits());
return false; return false;
} }
} }
...@@ -1830,7 +1825,7 @@ bool ProgramBinary::defineUniform(GLenum shader, const D3DXHANDLE &constantHandl ...@@ -1830,7 +1825,7 @@ bool ProgramBinary::defineUniform(GLenum shader, const D3DXHANDLE &constantHandl
std::string structIndex = (constantDescription.Elements > 1) ? ("[" + str(arrayIndex) + "]") : ""; std::string structIndex = (constantDescription.Elements > 1) ? ("[" + str(arrayIndex) + "]") : "";
if (!defineUniform(shader, fieldHandle, fieldDescription, name + constantDescription.Name + structIndex + ".")) if (!defineUniform(infoLog, shader, fieldHandle, fieldDescription, name + constantDescription.Name + structIndex + "."))
{ {
return false; return false;
} }
...@@ -2197,107 +2192,11 @@ void ProgramBinary::applyUniformniv(Uniform *targetUniform, GLsizei count, const ...@@ -2197,107 +2192,11 @@ void ProgramBinary::applyUniformniv(Uniform *targetUniform, GLsizei count, const
} }
} }
// append a santized message to the program info log.
// The D3D compiler includes a fake file path in some of the warning or error
// messages, so lets remove all occurrences of this fake file path from the log.
void ProgramBinary::appendToInfoLogSanitized(const char *message)
{
std::string msg(message);
size_t found;
do
{
found = msg.find(fakepath);
if (found != std::string::npos)
{
msg.erase(found, strlen(fakepath));
}
}
while (found != std::string::npos);
appendToInfoLog("%s\n", msg.c_str());
}
void ProgramBinary::appendToInfoLog(const char *format, ...)
{
if (!format)
{
return;
}
char info[1024];
va_list vararg;
va_start(vararg, format);
vsnprintf(info, sizeof(info), format, vararg);
va_end(vararg);
size_t infoLength = strlen(info);
if (!mInfoLog)
{
mInfoLog = new char[infoLength + 1];
strcpy(mInfoLog, info);
}
else
{
size_t logLength = strlen(mInfoLog);
char *newLog = new char[logLength + infoLength + 1];
strcpy(newLog, mInfoLog);
strcpy(newLog + logLength, info);
delete[] mInfoLog;
mInfoLog = newLog;
}
}
void ProgramBinary::resetInfoLog()
{
if (mInfoLog)
{
delete [] mInfoLog;
mInfoLog = NULL;
}
}
bool ProgramBinary::isValidated() const bool ProgramBinary::isValidated() const
{ {
return mValidated; return mValidated;
} }
int ProgramBinary::getInfoLogLength() const
{
if (!mInfoLog)
{
return 0;
}
else
{
return strlen(mInfoLog) + 1;
}
}
void ProgramBinary::getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog)
{
int index = 0;
if (bufSize > 0)
{
if (mInfoLog)
{
index = std::min(bufSize - 1, (int)strlen(mInfoLog));
memcpy(infoLog, mInfoLog, index);
}
infoLog[index] = '\0';
}
if (length)
{
*length = index;
}
}
void ProgramBinary::getActiveAttribute(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) void ProgramBinary::getActiveAttribute(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)
{ {
// Skip over inactive attributes // Skip over inactive attributes
...@@ -2448,12 +2347,10 @@ GLint ProgramBinary::getActiveUniformMaxLength() ...@@ -2448,12 +2347,10 @@ GLint ProgramBinary::getActiveUniformMaxLength()
return maxLength; return maxLength;
} }
void ProgramBinary::validate() void ProgramBinary::validate(InfoLog &infoLog)
{ {
resetInfoLog();
applyUniforms(); applyUniforms();
if (!validateSamplers(true)) if (!validateSamplers(&infoLog))
{ {
mValidated = false; mValidated = false;
} }
...@@ -2463,7 +2360,7 @@ void ProgramBinary::validate() ...@@ -2463,7 +2360,7 @@ void ProgramBinary::validate()
} }
} }
bool ProgramBinary::validateSamplers(bool logErrors) bool ProgramBinary::validateSamplers(InfoLog *infoLog)
{ {
// if any two active samplers in a program are of different types, but refer to the same // if any two active samplers in a program are of different types, but refer to the same
// texture image unit, and this is the current program, then ValidateProgram will fail, and // texture image unit, and this is the current program, then ValidateProgram will fail, and
...@@ -2485,9 +2382,9 @@ bool ProgramBinary::validateSamplers(bool logErrors) ...@@ -2485,9 +2382,9 @@ bool ProgramBinary::validateSamplers(bool logErrors)
if (unit >= maxCombinedTextureImageUnits) if (unit >= maxCombinedTextureImageUnits)
{ {
if (logErrors) if (infoLog)
{ {
appendToInfoLog("Sampler uniform (%d) exceeds MAX_COMBINED_TEXTURE_IMAGE_UNITS (%d)", unit, maxCombinedTextureImageUnits); infoLog->append("Sampler uniform (%d) exceeds MAX_COMBINED_TEXTURE_IMAGE_UNITS (%d)", unit, maxCombinedTextureImageUnits);
} }
return false; return false;
...@@ -2497,9 +2394,9 @@ bool ProgramBinary::validateSamplers(bool logErrors) ...@@ -2497,9 +2394,9 @@ bool ProgramBinary::validateSamplers(bool logErrors)
{ {
if (mSamplersPS[i].textureType != textureUnitType[unit]) if (mSamplersPS[i].textureType != textureUnitType[unit])
{ {
if (logErrors) if (infoLog)
{ {
appendToInfoLog("Samplers of conflicting types refer to the same texture image unit (%d).", unit); infoLog->append("Samplers of conflicting types refer to the same texture image unit (%d).", unit);
} }
return false; return false;
...@@ -2520,9 +2417,9 @@ bool ProgramBinary::validateSamplers(bool logErrors) ...@@ -2520,9 +2417,9 @@ bool ProgramBinary::validateSamplers(bool logErrors)
if (unit >= maxCombinedTextureImageUnits) if (unit >= maxCombinedTextureImageUnits)
{ {
if (logErrors) if (infoLog)
{ {
appendToInfoLog("Sampler uniform (%d) exceeds MAX_COMBINED_TEXTURE_IMAGE_UNITS (%d)", unit, maxCombinedTextureImageUnits); infoLog->append("Sampler uniform (%d) exceeds MAX_COMBINED_TEXTURE_IMAGE_UNITS (%d)", unit, maxCombinedTextureImageUnits);
} }
return false; return false;
...@@ -2532,9 +2429,9 @@ bool ProgramBinary::validateSamplers(bool logErrors) ...@@ -2532,9 +2429,9 @@ bool ProgramBinary::validateSamplers(bool logErrors)
{ {
if (mSamplersVS[i].textureType != textureUnitType[unit]) if (mSamplersVS[i].textureType != textureUnitType[unit])
{ {
if (logErrors) if (infoLog)
{ {
appendToInfoLog("Samplers of conflicting types refer to the same texture image unit (%d).", unit); infoLog->append("Samplers of conflicting types refer to the same texture image unit (%d).", unit);
} }
return false; return false;
......
...@@ -128,9 +128,7 @@ class ProgramBinary ...@@ -128,9 +128,7 @@ class ProgramBinary
void dirtyAllUniforms(); void dirtyAllUniforms();
void applyUniforms(); void applyUniforms();
bool link(const AttributeBindings &attributeBindings, FragmentShader *fragmentShader, VertexShader *vertexShader); bool link(InfoLog &infoLog, const AttributeBindings &attributeBindings, FragmentShader *fragmentShader, VertexShader *vertexShader);
int getInfoLogLength() const;
void getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog);
void getAttachedShaders(GLsizei maxCount, GLsizei *count, GLuint *shaders); void getAttachedShaders(GLsizei maxCount, GLsizei *count, GLuint *shaders);
void getActiveAttribute(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name); void getActiveAttribute(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name);
...@@ -141,8 +139,8 @@ class ProgramBinary ...@@ -141,8 +139,8 @@ class ProgramBinary
GLint getActiveUniformCount(); GLint getActiveUniformCount();
GLint getActiveUniformMaxLength(); GLint getActiveUniformMaxLength();
void validate(); void validate(InfoLog &infoLog);
bool validateSamplers(bool logErrors); bool validateSamplers(InfoLog *infoLog);
bool isValidated() const; bool isValidated() const;
static std::string decorateAttribute(const std::string &name); // Prepend an underscore static std::string decorateAttribute(const std::string &name); // Prepend an underscore
...@@ -151,15 +149,15 @@ class ProgramBinary ...@@ -151,15 +149,15 @@ class ProgramBinary
private: private:
DISALLOW_COPY_AND_ASSIGN(ProgramBinary); DISALLOW_COPY_AND_ASSIGN(ProgramBinary);
ID3D10Blob *compileToBinary(const char *hlsl, const char *profile, ID3DXConstantTable **constantTable); ID3D10Blob *compileToBinary(InfoLog &infoLog, const char *hlsl, const char *profile, ID3DXConstantTable **constantTable);
int packVaryings(const Varying *packing[][4], FragmentShader *fragmentShader); int packVaryings(InfoLog &infoLog, const Varying *packing[][4], FragmentShader *fragmentShader);
bool linkVaryings(std::string& pixelHLSL, std::string& vertexHLSL, FragmentShader *fragmentShader, VertexShader *vertexShader); bool linkVaryings(InfoLog &infoLog, std::string& pixelHLSL, std::string& vertexHLSL, FragmentShader *fragmentShader, VertexShader *vertexShader);
bool linkAttributes(const AttributeBindings &attributeBindings, FragmentShader *fragmentShader, VertexShader *vertexShader); bool linkAttributes(InfoLog &infoLog, const AttributeBindings &attributeBindings, FragmentShader *fragmentShader, VertexShader *vertexShader);
bool linkUniforms(GLenum shader, ID3DXConstantTable *constantTable); bool linkUniforms(InfoLog &infoLog, GLenum shader, ID3DXConstantTable *constantTable);
bool defineUniform(GLenum shader, const D3DXHANDLE &constantHandle, const D3DXCONSTANT_DESC &constantDescription, std::string name = ""); bool defineUniform(InfoLog &infoLog, GLenum shader, const D3DXHANDLE &constantHandle, const D3DXCONSTANT_DESC &constantDescription, std::string name = "");
bool defineUniform(GLenum shader, const D3DXCONSTANT_DESC &constantDescription, const std::string &name); bool defineUniform(GLenum shader, const D3DXCONSTANT_DESC &constantDescription, const std::string &name);
Uniform *createUniform(const D3DXCONSTANT_DESC &constantDescription, const std::string &name); Uniform *createUniform(const D3DXCONSTANT_DESC &constantDescription, const std::string &name);
bool applyUniformnfv(Uniform *targetUniform, const GLfloat *v); bool applyUniformnfv(Uniform *targetUniform, const GLfloat *v);
...@@ -170,12 +168,6 @@ class ProgramBinary ...@@ -170,12 +168,6 @@ class ProgramBinary
void applyUniformniv(Uniform *targetUniform, GLsizei count, const D3DXVECTOR4 *vector); void applyUniformniv(Uniform *targetUniform, GLsizei count, const D3DXVECTOR4 *vector);
void applyUniformnbv(Uniform *targetUniform, GLsizei count, int width, const GLboolean *v); void applyUniformnbv(Uniform *targetUniform, GLsizei count, int width, const GLboolean *v);
void appendToInfoLogSanitized(const char *message);
void appendToInfoLog(const char *info, ...);
void resetInfoLog();
static unsigned int issueSerial();
IDirect3DDevice9 *mDevice; IDirect3DDevice9 *mDevice;
IDirect3DPixelShader9 *mPixelExecutable; IDirect3DPixelShader9 *mPixelExecutable;
...@@ -212,7 +204,6 @@ class ProgramBinary ...@@ -212,7 +204,6 @@ class ProgramBinary
GLint mDxFrontCCWLocation; GLint mDxFrontCCWLocation;
GLint mDxPointsOrLinesLocation; GLint mDxPointsOrLinesLocation;
char *mInfoLog;
bool mValidated; bool mValidated;
}; };
} }
......
...@@ -6444,13 +6444,7 @@ void __stdcall glValidateProgram(GLuint program) ...@@ -6444,13 +6444,7 @@ void __stdcall glValidateProgram(GLuint program)
} }
} }
gl::ProgramBinary *programBinary = programObject->getProgramBinary(); programObject->validate();
if (!programBinary)
{
return;
}
programBinary->validate();
} }
} }
catch(std::bad_alloc&) catch(std::bad_alloc&)
......
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