Implements ValidateProgram

TRAC #11654 Signed-off-by: Andrew Lewycky Signed-off-by: Daniel Koch Author: Shannon Woods git-svn-id: https://angleproject.googlecode.com/svn/trunk@196 736b8ea6-26fd-11df-bfd4-992fa37f6226
parent 0b6b834a
...@@ -1861,6 +1861,11 @@ void Context::drawArrays(GLenum mode, GLint first, GLsizei count) ...@@ -1861,6 +1861,11 @@ void Context::drawArrays(GLenum mode, GLint first, GLsizei count)
return; return;
} }
if (!getCurrentProgram()->validateSamplers())
{
return error(GL_INVALID_OPERATION);
}
if (!applyRenderTarget(false)) if (!applyRenderTarget(false))
{ {
return error(GL_INVALID_FRAMEBUFFER_OPERATION); return error(GL_INVALID_FRAMEBUFFER_OPERATION);
...@@ -1903,6 +1908,11 @@ void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const void* ...@@ -1903,6 +1908,11 @@ void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const void*
return; return;
} }
if (!getCurrentProgram()->validateSamplers())
{
return error(GL_INVALID_OPERATION);
}
if (!applyRenderTarget(false)) if (!applyRenderTarget(false))
{ {
return error(GL_INVALID_FRAMEBUFFER_OPERATION); return error(GL_INVALID_FRAMEBUFFER_OPERATION);
......
...@@ -48,6 +48,7 @@ Program::Program() ...@@ -48,6 +48,7 @@ Program::Program()
mPixelHLSL = NULL; mPixelHLSL = NULL;
mVertexHLSL = NULL; mVertexHLSL = NULL;
mInfoLog = NULL; mInfoLog = NULL;
mValidated = false;
unlink(); unlink();
...@@ -1882,6 +1883,14 @@ void Program::appendToInfoLog(const char *format, ...) ...@@ -1882,6 +1883,14 @@ void Program::appendToInfoLog(const char *format, ...)
} }
} }
void Program::resetInfoLog()
{
if (mInfoLog)
{
delete [] mInfoLog;
}
}
// Returns the program object to an unlinked state, after detaching a shader, before re-linking, or at destruction // Returns the program object to an unlinked state, after detaching a shader, before re-linking, or at destruction
void Program::unlink(bool destroy) void Program::unlink(bool destroy)
{ {
...@@ -1960,6 +1969,11 @@ bool Program::isLinked() ...@@ -1960,6 +1969,11 @@ bool Program::isLinked()
return mLinked; return mLinked;
} }
bool Program::isValidated() const
{
return mValidated;
}
int Program::getInfoLogLength() const int Program::getInfoLogLength() const
{ {
if (!mInfoLog) if (!mInfoLog)
...@@ -2164,4 +2178,49 @@ bool Program::isFlaggedForDeletion() const ...@@ -2164,4 +2178,49 @@ bool Program::isFlaggedForDeletion() const
{ {
return mDeleteStatus; return mDeleteStatus;
} }
void Program::validate()
{
resetInfoLog();
if (!isLinked())
{
appendToInfoLog("Program has not been successfully linked.");
mValidated = false;
}
else if (!validateSamplers())
{
appendToInfoLog("Samplers of conflicting types refer to the same texture image unit.");
mValidated = false;
}
else
{
mValidated = true;
}
}
bool Program::validateSamplers() const
{
// 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
// DrawArrays and DrawElements will issue the INVALID_OPERATION error.
std::map<int, SamplerType> samplerMap;
for (unsigned int i = 0; i < MAX_TEXTURE_IMAGE_UNITS; ++i)
{
if (mSamplers[i].active)
{
if (samplerMap.find(mSamplers[i].logicalTextureUnit) != samplerMap.end())
{
if (mSamplers[i].type != samplerMap[mSamplers[i].logicalTextureUnit])
return false;
}
else
{
samplerMap[mSamplers[i].logicalTextureUnit] = mSamplers[i].type;
}
}
}
return true;
}
} }
...@@ -102,6 +102,10 @@ class Program ...@@ -102,6 +102,10 @@ class Program
void flagForDeletion(); void flagForDeletion();
bool isFlaggedForDeletion() const; bool isFlaggedForDeletion() const;
void validate();
bool validateSamplers() const;
bool isValidated() const;
private: private:
DISALLOW_COPY_AND_ASSIGN(Program); DISALLOW_COPY_AND_ASSIGN(Program);
...@@ -150,6 +154,7 @@ class Program ...@@ -150,6 +154,7 @@ class Program
bool applyUniform4iv(GLint location, GLsizei count, const GLint *v); bool applyUniform4iv(GLint location, GLsizei count, const GLint *v);
void appendToInfoLog(const char *info, ...); void appendToInfoLog(const char *info, ...);
void resetInfoLog();
FragmentShader *mFragmentShader; FragmentShader *mFragmentShader;
VertexShader *mVertexShader; VertexShader *mVertexShader;
...@@ -183,6 +188,7 @@ class Program ...@@ -183,6 +188,7 @@ class Program
bool mLinked; bool mLinked;
bool mDeleteStatus; // Flag to indicate that the program can be deleted when no longer in use bool mDeleteStatus; // Flag to indicate that the program can be deleted when no longer in use
char *mInfoLog; char *mInfoLog;
bool mValidated;
}; };
} }
......
...@@ -2424,8 +2424,7 @@ void __stdcall glGetProgramiv(GLuint program, GLenum pname, GLint* params) ...@@ -2424,8 +2424,7 @@ void __stdcall glGetProgramiv(GLuint program, GLenum pname, GLint* params)
*params = programObject->isLinked(); *params = programObject->isLinked();
return; return;
case GL_VALIDATE_STATUS: case GL_VALIDATE_STATUS:
UNIMPLEMENTED(); // FIXME *params = programObject->isValidated();
*params = GL_TRUE;
return; return;
case GL_INFO_LOG_LENGTH: case GL_INFO_LOG_LENGTH:
*params = programObject->getInfoLogLength(); *params = programObject->getInfoLogLength();
...@@ -4723,7 +4722,26 @@ void __stdcall glValidateProgram(GLuint program) ...@@ -4723,7 +4722,26 @@ void __stdcall glValidateProgram(GLuint program)
try try
{ {
UNIMPLEMENTED(); // FIXME gl::Context *context = gl::getContext();
if (context)
{
gl::Program *programObject = context->getProgram(program);
if (!programObject)
{
if (context->getShader(program))
{
return error(GL_INVALID_OPERATION);
}
else
{
return error(GL_INVALID_VALUE);
}
}
programObject->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