Compiler - implement shader and program queries
TRAC #11599
Signed-off-by: Shannon Woods
Signed-off-by: Daniel Koch
Author: Nicolas Capens
git-svn-id: https://angleproject.googlecode.com/svn/trunk@76 736b8ea6-26fd-11df-bfd4-992fa37f6226
diff --git a/src/libGLESv2/Program.cpp b/src/libGLESv2/Program.cpp
index a9f2f64..5686b16 100644
--- a/src/libGLESv2/Program.cpp
+++ b/src/libGLESv2/Program.cpp
@@ -41,6 +41,8 @@
mAttributeName[index] = NULL;
}
+ mInfoLog = NULL;
+
unlink();
mDeleteStatus = false;
@@ -107,6 +109,11 @@
return true;
}
+int Program::getAttachedShadersCount() const
+{
+ return (mVertexShader ? 1 : 0) + (mFragmentShader ? 1 : 0);
+}
+
IDirect3DPixelShader9 *Program::getPixelShader()
{
return mPixelExecutable;
@@ -385,6 +392,7 @@
if (errorMessage)
{
const char *message = (const char*)errorMessage->GetBufferPointer();
+
TRACE("\n%s", hlsl);
TRACE("\n%s", message);
}
@@ -404,6 +412,9 @@
unlink();
+ delete[] mInfoLog;
+ mInfoLog = NULL;
+
if (!mFragmentShader || !mFragmentShader->isCompiled())
{
return;
@@ -910,6 +921,32 @@
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 @@
delete[] mAttributeName[index];
mAttributeName[index] = NULL;
}
+
+ delete[] mInfoLog;
+ mInfoLog = NULL;
}
if (mPixelExecutable)
@@ -982,6 +1022,42 @@
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 157e36e..0ce0add 100644
--- a/src/libGLESv2/Program.h
+++ b/src/libGLESv2/Program.h
@@ -55,6 +55,7 @@
bool attachShader(Shader *shader);
bool detachShader(Shader *shader);
+ int getAttachedShadersCount() const;
IDirect3DPixelShader9 *getPixelShader();
IDirect3DVertexShader9 *getVertexShader();
@@ -81,6 +82,8 @@
void link();
bool isLinked();
+ int getInfoLogLength() const;
+ void getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog);
void flagForDeletion();
bool isFlaggedForDeletion() const;
@@ -105,6 +108,8 @@
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 @@
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 f95b4c7..b17a6c9 100644
--- a/src/libGLESv2/Shader.cpp
+++ b/src/libGLESv2/Shader.cpp
@@ -24,7 +24,7 @@
{
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 @@
{
delete[] mSource;
delete[] mHlsl;
- delete[] mErrors;
+ delete[] mInfoLog;
}
void Shader::setSource(GLsizei count, const char **string, const GLint *length)
@@ -89,6 +89,78 @@
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 @@
return mDeleteStatus == true && mAttachCount == 0;
}
+bool Shader::isFlaggedForDeletion() const
+{
+ return mDeleteStatus;
+}
+
void Shader::flagForDeletion()
{
mDeleteStatus = true;
@@ -142,8 +219,8 @@
TRACE("\n%s", mSource);
- delete[] mErrors;
- mErrors = NULL;
+ delete[] mInfoLog;
+ mInfoLog = NULL;
TBuiltInResource resources;
@@ -169,10 +246,10 @@
}
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 3bac7f8..e555064 100644
--- a/src/libGLESv2/Shader.h
+++ b/src/libGLESv2/Shader.h
@@ -31,6 +31,10 @@
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 @@
void detach();
bool isAttached() const;
bool isDeletable() const;
+ bool isFlaggedForDeletion() const;
void flagForDeletion();
static void releaseCompiler();
@@ -54,7 +59,7 @@
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 6757249..ec4f0fa 100644
--- a/src/libGLESv2/libGLESv2.cpp
+++ b/src/libGLESv2/libGLESv2.cpp
@@ -1928,8 +1928,7 @@
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 @@
*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 @@
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 @@
*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 @@
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 @@
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&)
{