Commit ece12535 by Yunchao He Committed by Commit Bot

ES31: Fix the issue for relink rendering/compute program.

When link or relink fails, if we try to install the unsuccessfully linked program (via UseProgram) and start rendering or dispatch compute, We can not always report INVALID_OPERATION for rendering/compute pipeline. The result depends on the previous state: Whether a valid program has been installed in pipeline before. If a valid program has been installed, it should be OK to use the old executable residing in the GL state to start rendering or dispatch compute. No error should be reported. This change also add unit tests for unsuccessfully linked/relinked program for rendering pipeline to avoid potential error. If a program successfully relinks when it is in use, the program might change from a rendering program to a compute program in theory, or vice versa. BUG=angleproject:2266 Change-Id: I4726112af2bc74f5beef25e35d2fcaa9f31e0768 Reviewed-on: https://chromium-review.googlesource.com/784273Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarCorentin Wallez <cwallez@chromium.org> Commit-Queue: Corentin Wallez <cwallez@chromium.org>
parent 5f19810d
...@@ -977,6 +977,8 @@ Error Program::link(const gl::Context *context) ...@@ -977,6 +977,8 @@ Error Program::link(const gl::Context *context)
setUniformValuesFromBindingQualifiers(); setUniformValuesFromBindingQualifiers();
// According to GLES 3.0/3.1 spec for LinkProgram and UseProgram,
// Only successfully linked program can replace the executables.
ASSERT(mLinked); ASSERT(mLinked);
updateLinkedShaderStages(); updateLinkedShaderStages();
...@@ -999,6 +1001,8 @@ Error Program::link(const gl::Context *context) ...@@ -999,6 +1001,8 @@ Error Program::link(const gl::Context *context)
void Program::updateLinkedShaderStages() void Program::updateLinkedShaderStages()
{ {
mState.mLinkedShaderStages.reset();
if (mState.mAttachedVertexShader) if (mState.mAttachedVertexShader)
{ {
mState.mLinkedShaderStages.set(SHADER_VERTEX); mState.mLinkedShaderStages.set(SHADER_VERTEX);
...@@ -1036,7 +1040,6 @@ void Program::unlink() ...@@ -1036,7 +1040,6 @@ void Program::unlink()
mState.mSamplerBindings.clear(); mState.mSamplerBindings.clear();
mState.mImageBindings.clear(); mState.mImageBindings.clear();
mState.mNumViews = -1; mState.mNumViews = -1;
mState.mLinkedShaderStages.reset();
mValidated = false; mValidated = false;
......
...@@ -2505,8 +2505,7 @@ bool ValidateDrawBase(ValidationContext *context, GLenum mode, GLsizei count) ...@@ -2505,8 +2505,7 @@ bool ValidateDrawBase(ValidationContext *context, GLenum mode, GLsizei count)
// vertex shader stage or fragment shader stage is a undefined behaviour. // vertex shader stage or fragment shader stage is a undefined behaviour.
// But ANGLE should clearly generate an INVALID_OPERATION error instead of // But ANGLE should clearly generate an INVALID_OPERATION error instead of
// produce undefined result. // produce undefined result.
if (program->isLinked() && if (!program->hasLinkedVertexShader() || !program->hasLinkedFragmentShader())
(!program->hasLinkedVertexShader() || !program->hasLinkedFragmentShader()))
{ {
context->handleError(InvalidOperation() << "It is a undefined behaviour to render without " context->handleError(InvalidOperation() << "It is a undefined behaviour to render without "
"vertex shader stage or fragment shader stage."); "vertex shader stage or fragment shader stage.");
......
...@@ -1391,11 +1391,9 @@ bool ValidateDispatchCompute(Context *context, ...@@ -1391,11 +1391,9 @@ bool ValidateDispatchCompute(Context *context,
return false; return false;
} }
if (!program->isLinked() || !program->hasLinkedComputeShader()) if (!program->hasLinkedComputeShader())
{ {
context->handleError( context->handleError(InvalidOperation() << "Program contains no compute shaders.");
InvalidOperation()
<< "Program has not been successfully linked, or program contains no compute shaders.");
return false; return false;
} }
......
...@@ -53,6 +53,7 @@ ...@@ -53,6 +53,7 @@
'<(angle_path)/src/tests/gl_tests/IndexedPointsTest.cpp', '<(angle_path)/src/tests/gl_tests/IndexedPointsTest.cpp',
'<(angle_path)/src/tests/gl_tests/InstancingTest.cpp', '<(angle_path)/src/tests/gl_tests/InstancingTest.cpp',
'<(angle_path)/src/tests/gl_tests/LineLoopTest.cpp', '<(angle_path)/src/tests/gl_tests/LineLoopTest.cpp',
'<(angle_path)/src/tests/gl_tests/LinkAndRelinkTest.cpp',
'<(angle_path)/src/tests/gl_tests/MaxTextureSizeTest.cpp', '<(angle_path)/src/tests/gl_tests/MaxTextureSizeTest.cpp',
'<(angle_path)/src/tests/gl_tests/MipmapTest.cpp', '<(angle_path)/src/tests/gl_tests/MipmapTest.cpp',
'<(angle_path)/src/tests/gl_tests/MultisampleCompatibilityTest.cpp', '<(angle_path)/src/tests/gl_tests/MultisampleCompatibilityTest.cpp',
......
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