Commit e1728549 by Gregoire Payen de La Garanderie Committed by Jamie Madill

Unwritten shader output variables should not crash.

BUG=angle:862 Change-Id: I8e7fa9b0d00bb1b2a32a8d60d8ceda998cea8e8c Reviewed-on: https://chromium-review.googlesource.com/239160Tested-by: 's avatarGregoire Payen de La Garanderie <Gregory.Payen@imgtec.com> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent edd84e41
...@@ -72,19 +72,18 @@ std::string HLSLTypeString(GLenum type) ...@@ -72,19 +72,18 @@ std::string HLSLTypeString(GLenum type)
return HLSLComponentTypeString(gl::VariableComponentType(type), gl::VariableComponentCount(type)); return HLSLComponentTypeString(gl::VariableComponentType(type), gl::VariableComponentCount(type));
} }
const PixelShaderOutputVariable &GetOutputAtLocation(const std::vector<PixelShaderOutputVariable> &outputVariables, const PixelShaderOutputVariable *FindOutputAtLocation(const std::vector<PixelShaderOutputVariable> &outputVariables,
unsigned int location) unsigned int location)
{ {
for (size_t variableIndex = 0; variableIndex < outputVariables.size(); ++variableIndex) for (size_t variableIndex = 0; variableIndex < outputVariables.size(); ++variableIndex)
{ {
if (outputVariables[variableIndex].outputIndex == location) if (outputVariables[variableIndex].outputIndex == location)
{ {
return outputVariables[variableIndex]; return &outputVariables[variableIndex];
} }
} }
UNREACHABLE(); return NULL;
return outputVariables[0];
} }
const std::string VERTEX_ATTRIBUTE_STUB_STRING = "@@ VERTEX ATTRIBUTES @@"; const std::string VERTEX_ATTRIBUTE_STUB_STRING = "@@ VERTEX ATTRIBUTES @@";
...@@ -457,12 +456,18 @@ std::string DynamicHLSL::generatePixelShaderForOutputSignature(const std::string ...@@ -457,12 +456,18 @@ std::string DynamicHLSL::generatePixelShaderForOutputSignature(const std::string
{ {
unsigned int location = (binding - GL_COLOR_ATTACHMENT0); unsigned int location = (binding - GL_COLOR_ATTACHMENT0);
const PixelShaderOutputVariable &outputVariable = GetOutputAtLocation(outputVariables, location); const PixelShaderOutputVariable *outputVariable = FindOutputAtLocation(outputVariables, location);
declarationHLSL += " " + HLSLTypeString(outputVariable.type) + " " + outputVariable.name + // OpenGL ES 3.0 spec $4.2.1
" : " + targetSemantic + Str(layoutIndex) + ";\n"; // If [...] not all user-defined output variables are written, the values of fragment colors
// corresponding to unwritten variables are similarly undefined.
if (outputVariable)
{
declarationHLSL += " " + HLSLTypeString(outputVariable->type) + " " + outputVariable->name +
" : " + targetSemantic + Str(layoutIndex) + ";\n";
copyHLSL += " output." + outputVariable.name + " = " + outputVariable.source + ";\n"; copyHLSL += " output." + outputVariable->name + " = " + outputVariable->source + ";\n";
}
} }
} }
......
...@@ -287,3 +287,38 @@ TYPED_TEST(DrawBuffersTest, FirstHalfNULL) ...@@ -287,3 +287,38 @@ TYPED_TEST(DrawBuffersTest, FirstHalfNULL)
glDeleteProgram(program); glDeleteProgram(program);
} }
TYPED_TEST(DrawBuffersTest, UnwrittenOutputVariablesShouldNotCrash)
{
// Bind two render targets but use a shader which writes only to the first one.
glBindTexture(GL_TEXTURE_2D, mTextures[0]);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[0], 0);
glBindTexture(GL_TEXTURE_2D, mTextures[1]);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, mTextures[1], 0);
bool flags[8] = { true, false };
GLuint program;
setupMRTProgram(flags, &program);
const GLenum bufs[] =
{
GL_COLOR_ATTACHMENT0,
GL_COLOR_ATTACHMENT1,
GL_NONE,
GL_NONE,
};
glUseProgram(program);
glDrawBuffersEXT(4, bufs);
// This call should not crash when we dynamically generate the HLSL code.
glDrawArrays(GL_TRIANGLES, 0, 3);
verifyAttachment(0, mTextures[0]);
EXPECT_GL_NO_ERROR();
glDeleteProgram(program);
}
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