diff --git a/src/libGLESv2/Program.cpp b/src/libGLESv2/Program.cpp index a9f2f644c..5686b16a4 100644 --- a/src/libGLESv2/Program.cpp +++ b/src/libGLESv2/Program.cpp @@ -41,6 +41,8 @@ Program::Program() mAttributeName[index] = NULL; } + mInfoLog = NULL; + unlink(); mDeleteStatus = false; @@ -107,6 +109,11 @@ bool Program::detachShader(Shader *shader) return true; } +int Program::getAttachedShadersCount() const +{ + return (mVertexShader ? 1 : 0) + (mFragmentShader ? 1 : 0); +} + IDirect3DPixelShader9 *Program::getPixelShader() { return mPixelExecutable; @@ -385,6 +392,7 @@ ID3DXBuffer *Program::compileToBinary(const char *hlsl, const char *profile, ID3 if (errorMessage) { const char *message = (const char*)errorMessage->GetBufferPointer(); + TRACE("\n%s", hlsl); TRACE("\n%s", message); } @@ -404,6 +412,9 @@ void Program::link() unlink(); + delete[] mInfoLog; + mInfoLog = NULL; + if (!mFragmentShader || !mFragmentShader->isCompiled()) { return; @@ -910,6 +921,32 @@ bool Program::applyUniform1iv(GLint location, GLsizei count, const GLint *v) return true; } +void Program::appendToInfoLog(const char *info) +{ + if (!info) + { + return; + } + + 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; + } +} + // Returns the program object to an unlinked state, after detaching a shader, before re-linking, or at destruction void Program::unlink(bool destroy) { @@ -932,6 +969,9 @@ void Program::unlink(bool destroy) delete[] mAttributeName[index]; mAttributeName[index] = NULL; } + + delete[] mInfoLog; + mInfoLog = NULL; } if (mPixelExecutable) @@ -982,6 +1022,42 @@ bool Program::isLinked() return mLinked; } +int Program::getInfoLogLength() const +{ + if (!mInfoLog) + { + return 0; + } + else + { + return strlen(mInfoLog) + 1; + } +} + +void Program::getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog) +{ + int index = 0; + + if (mInfoLog) + { + while (index < bufSize - 1 && index < (int)strlen(mInfoLog)) + { + infoLog[index] = mInfoLog[index]; + index++; + } + } + + if (bufSize) + { + infoLog[index] = '\0'; + } + + if (length) + { + *length = index; + } +} + void Program::flagForDeletion() { mDeleteStatus = true; diff --git a/src/libGLESv2/Program.h b/src/libGLESv2/Program.h index 157e36e65..0ce0add50 100644 --- a/src/libGLESv2/Program.h +++ b/src/libGLESv2/Program.h @@ -55,6 +55,7 @@ class Program bool attachShader(Shader *shader); bool detachShader(Shader *shader); + int getAttachedShadersCount() const; IDirect3DPixelShader9 *getPixelShader(); IDirect3DVertexShader9 *getVertexShader(); @@ -81,6 +82,8 @@ class Program void link(); bool isLinked(); + int getInfoLogLength() const; + void getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog); void flagForDeletion(); bool isFlaggedForDeletion() const; @@ -105,6 +108,8 @@ class Program bool applyUniformMatrix4fv(GLint location, GLsizei count, const GLfloat *value); bool applyUniform1iv(GLint location, GLsizei count, const GLint *v); + void appendToInfoLog(const char *info); + FragmentShader *mFragmentShader; VertexShader *mVertexShader; @@ -130,6 +135,7 @@ class Program bool mLinked; bool mDeleteStatus; // Flag to indicate that the program can be deleted when no longer in use + char *mInfoLog; }; } diff --git a/src/libGLESv2/Shader.cpp b/src/libGLESv2/Shader.cpp index f95b4c751..b17a6c983 100644 --- a/src/libGLESv2/Shader.cpp +++ b/src/libGLESv2/Shader.cpp @@ -24,7 +24,7 @@ Shader::Shader() { mSource = NULL; mHlsl = NULL; - mErrors = NULL; + mInfoLog = NULL; // Perform a one-time initialization of the shader compiler (or after being destructed by releaseCompiler) if (!mFragmentCompiler) @@ -46,7 +46,7 @@ Shader::~Shader() { delete[] mSource; delete[] mHlsl; - delete[] mErrors; + delete[] mInfoLog; } void Shader::setSource(GLsizei count, const char **string, const GLint *length) @@ -89,6 +89,78 @@ void Shader::setSource(GLsizei count, const char **string, const GLint *length) mSource[totalLength] = '\0'; } +int Shader::getInfoLogLength() const +{ + if (!mInfoLog) + { + return 0; + } + else + { + return strlen(mInfoLog) + 1; + } +} + +void Shader::getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog) +{ + int index = 0; + + if (mInfoLog) + { + while (index < bufSize - 1 && index < (int)strlen(mInfoLog)) + { + infoLog[index] = mInfoLog[index]; + index++; + } + } + + if (bufSize) + { + infoLog[index] = '\0'; + } + + if (length) + { + *length = index; + } +} + +int Shader::getSourceLength() const +{ + if (!mSource) + { + return 0; + } + else + { + return strlen(mSource) + 1; + } +} + +void Shader::getSource(GLsizei bufSize, GLsizei *length, char *source) +{ + int index = 0; + + if (mSource) + { + while (index < bufSize - 1 && index < (int)strlen(mInfoLog)) + { + source[index] = mSource[index]; + index++; + } + } + + if (bufSize) + { + source[index] = '\0'; + } + + if (length) + { + *length = index; + } +} + bool Shader::isCompiled() { return mHlsl != NULL; @@ -119,6 +191,11 @@ bool Shader::isDeletable() const return mDeleteStatus == true && mAttachCount == 0; } +bool Shader::isFlaggedForDeletion() const +{ + return mDeleteStatus; +} + void Shader::flagForDeletion() { mDeleteStatus = true; @@ -142,8 +219,8 @@ void Shader::compileToHLSL(void *compiler) TRACE("\n%s", mSource); - delete[] mErrors; - mErrors = NULL; + delete[] mInfoLog; + mInfoLog = NULL; TBuiltInResource resources; @@ -169,10 +246,10 @@ void Shader::compileToHLSL(void *compiler) } else { - mErrors = new char[strlen(info) + 1]; - strcpy(mErrors, info); + mInfoLog = new char[strlen(info) + 1]; + strcpy(mInfoLog, info); - TRACE("\n%s", mErrors); + TRACE("\n%s", mInfoLog); } } diff --git a/src/libGLESv2/Shader.h b/src/libGLESv2/Shader.h index 3bac7f859..e55506456 100644 --- a/src/libGLESv2/Shader.h +++ b/src/libGLESv2/Shader.h @@ -31,6 +31,10 @@ class Shader void deleteSource(); void setSource(GLsizei count, const char **string, const GLint *length); + int getInfoLogLength() const; + void getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog); + int getSourceLength() const; + void getSource(GLsizei bufSize, GLsizei *length, char *source); virtual void compile() = 0; bool isCompiled(); @@ -40,6 +44,7 @@ class Shader void detach(); bool isAttached() const; bool isDeletable() const; + bool isFlaggedForDeletion() const; void flagForDeletion(); static void releaseCompiler(); @@ -54,7 +59,7 @@ class Shader char *mSource; char *mHlsl; - char *mErrors; + char *mInfoLog; static void *mFragmentCompiler; static void *mVertexCompiler; diff --git a/src/libGLESv2/libGLESv2.cpp b/src/libGLESv2/libGLESv2.cpp index 67572495e..ec4f0faac 100644 --- a/src/libGLESv2/libGLESv2.cpp +++ b/src/libGLESv2/libGLESv2.cpp @@ -1928,8 +1928,7 @@ void __stdcall glGetProgramiv(GLuint program, GLenum pname, GLint* params) switch (pname) { case GL_DELETE_STATUS: - UNIMPLEMENTED(); // FIXME - *params = GL_FALSE; + *params = programObject->isFlaggedForDeletion(); return; case GL_LINK_STATUS: *params = programObject->isLinked(); @@ -1939,12 +1938,10 @@ void __stdcall glGetProgramiv(GLuint program, GLenum pname, GLint* params) *params = GL_TRUE; return; case GL_INFO_LOG_LENGTH: - UNIMPLEMENTED(); // FIXME - *params = 0; + *params = programObject->getInfoLogLength(); return; case GL_ATTACHED_SHADERS: - UNIMPLEMENTED(); // FIXME - *params = 2; + *params = programObject->getAttachedShadersCount(); return; case GL_ACTIVE_ATTRIBUTES: UNIMPLEMENTED(); // FIXME @@ -1985,7 +1982,19 @@ void __stdcall glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* len return error(GL_INVALID_VALUE); } - UNIMPLEMENTED(); // FIXME + gl::Context *context = gl::getContext(); + + if (context) + { + gl::Program *programObject = context->getProgram(program); + + if (!programObject) + { + return error(GL_INVALID_VALUE); + } + + programObject->getInfoLog(bufsize, length, infolog); + } } catch(std::bad_alloc&) { @@ -2030,19 +2039,16 @@ void __stdcall glGetShaderiv(GLuint shader, GLenum pname, GLint* params) *params = shaderObject->getType(); return; case GL_DELETE_STATUS: - UNIMPLEMENTED(); // FIXME - *params = GL_FALSE; + *params = shaderObject->isFlaggedForDeletion(); return; case GL_COMPILE_STATUS: *params = shaderObject->isCompiled() ? GL_TRUE : GL_FALSE; return; case GL_INFO_LOG_LENGTH: - UNIMPLEMENTED(); // FIXME - *params = 0; + *params = shaderObject->getInfoLogLength(); return; case GL_SHADER_SOURCE_LENGTH: - UNIMPLEMENTED(); // FIXME - *params = 1; + *params = shaderObject->getSourceLength(); return; default: return error(GL_INVALID_ENUM); @@ -2067,7 +2073,19 @@ void __stdcall glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* lengt return error(GL_INVALID_VALUE); } - UNIMPLEMENTED(); // FIXME + gl::Context *context = gl::getContext(); + + if (context) + { + gl::Shader *shaderObject = context->getShader(shader); + + if (!shaderObject) + { + return error(GL_INVALID_VALUE); + } + + shaderObject->getInfoLog(bufsize, length, infolog); + } } catch(std::bad_alloc&) { @@ -2102,7 +2120,19 @@ void __stdcall glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length return error(GL_INVALID_VALUE); } - UNIMPLEMENTED(); // FIXME + gl::Context *context = gl::getContext(); + + if (context) + { + gl::Shader *shaderObject = context->getShader(shader); + + if (!shaderObject) + { + return error(GL_INVALID_VALUE); + } + + shaderObject->getSource(bufsize, length, source); + } } catch(std::bad_alloc&) {