Commit 0e883134 by Jiawei Shao Committed by Commit Bot

ES31: Support EXT_geometry_shader in GLSL compiler

This patch intends to support "EXT_geometry_shader" as a valid extension string in ANGLE GLSL compiler. We decide to support it because in dEQP-GLES31 all geometry shader related tests are using "EXT_geometry_shader" instead of "OES_geometry_shader". 1. Support new extension string "EXT_geometry_shader" 2. Enable geometry shader layout qualifiers with EXT_geometry_shader 3. Enable geometry shader builtins with EXT_geometry_shader BUG=angleproject:1941 TEST=angle_unittests Change-Id: Iaedd01a9100ccf56243c957db36ff0c983d17060 Reviewed-on: https://chromium-review.googlesource.com/737933Reviewed-by: 's avatarCorentin Wallez <cwallez@chromium.org> Reviewed-by: 's avatarOlli Etuaho <oetuaho@nvidia.com> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>
parent c5de4d29
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
OP(EXT_blend_func_extended) \ OP(EXT_blend_func_extended) \
OP(EXT_draw_buffers) \ OP(EXT_draw_buffers) \
OP(EXT_frag_depth) \ OP(EXT_frag_depth) \
OP(EXT_geometry_shader) \
OP(EXT_shader_framebuffer_fetch) \ OP(EXT_shader_framebuffer_fetch) \
OP(EXT_shader_texture_lod) \ OP(EXT_shader_texture_lod) \
OP(EXT_YUV_target) \ OP(EXT_YUV_target) \
......
...@@ -23,6 +23,7 @@ enum class TExtension ...@@ -23,6 +23,7 @@ enum class TExtension
EXT_blend_func_extended, EXT_blend_func_extended,
EXT_draw_buffers, EXT_draw_buffers,
EXT_frag_depth, EXT_frag_depth,
EXT_geometry_shader,
EXT_shader_framebuffer_fetch, EXT_shader_framebuffer_fetch,
EXT_shader_texture_lod, EXT_shader_texture_lod,
EXT_YUV_target, EXT_YUV_target,
......
...@@ -1091,6 +1091,7 @@ void InitExtensionBehavior(const ShBuiltInResources &resources, TExtensionBehavi ...@@ -1091,6 +1091,7 @@ void InitExtensionBehavior(const ShBuiltInResources &resources, TExtensionBehavi
if (resources.OES_geometry_shader) if (resources.OES_geometry_shader)
{ {
extBehavior[TExtension::OES_geometry_shader] = EBhUndefined; extBehavior[TExtension::OES_geometry_shader] = EBhUndefined;
extBehavior[TExtension::EXT_geometry_shader] = EBhUndefined;
} }
} }
......
...@@ -1159,6 +1159,7 @@ void TParseContext::checkIsParameterQualifierValid( ...@@ -1159,6 +1159,7 @@ void TParseContext::checkIsParameterQualifierValid(
bool TParseContext::checkCanUseExtension(const TSourceLoc &line, TExtension extension) bool TParseContext::checkCanUseExtension(const TSourceLoc &line, TExtension extension)
{ {
ASSERT(extension != TExtension::UNDEFINED); ASSERT(extension != TExtension::UNDEFINED);
ASSERT(extension != TExtension::EXT_geometry_shader);
const TExtensionBehavior &extBehavior = extensionBehavior(); const TExtensionBehavior &extBehavior = extensionBehavior();
TExtensionBehavior::const_iterator iter = extBehavior.find(extension); TExtensionBehavior::const_iterator iter = extBehavior.find(extension);
if (iter == extBehavior.end()) if (iter == extBehavior.end())
...@@ -1169,11 +1170,53 @@ bool TParseContext::checkCanUseExtension(const TSourceLoc &line, TExtension exte ...@@ -1169,11 +1170,53 @@ bool TParseContext::checkCanUseExtension(const TSourceLoc &line, TExtension exte
// In GLSL ES, an extension's default behavior is "disable". // In GLSL ES, an extension's default behavior is "disable".
if (iter->second == EBhDisable || iter->second == EBhUndefined) if (iter->second == EBhDisable || iter->second == EBhUndefined)
{ {
// We also need to check EXT_geometry_shader because internally we always use
// TExtension::OES_geometry_shader to represent both OES_geometry_shader and
// EXT_geometry_shader.
if (extension == TExtension::OES_geometry_shader)
{
TExtensionBehavior::const_iterator iterExt =
extBehavior.find(TExtension::EXT_geometry_shader);
ASSERT(iterExt != extBehavior.end());
if (iterExt->second == EBhUndefined)
{
error(line, "extension is disabled",
GetExtensionNameString(TExtension::OES_geometry_shader));
return false;
}
if (iterExt->second == EBhDisable)
{
error(line, "extension is disabled",
GetExtensionNameString(TExtension::EXT_geometry_shader));
return false;
}
if (iterExt->second == EBhWarn)
{
warning(line, "extension is being used",
GetExtensionNameString(TExtension::EXT_geometry_shader));
}
return true;
}
error(line, "extension is disabled", GetExtensionNameString(extension)); error(line, "extension is disabled", GetExtensionNameString(extension));
return false; return false;
} }
if (iter->second == EBhWarn) if (iter->second == EBhWarn)
{ {
if (extension == TExtension::OES_geometry_shader)
{
TExtensionBehavior::const_iterator iterExt =
extBehavior.find(TExtension::EXT_geometry_shader);
ASSERT(iterExt != extBehavior.end());
// We should output no warnings when OES_geometry_shader is declared as "warn" and
// EXT_geometry_shader is declared as "require" or "enable".
if (iterExt->second == EBhRequire || iterExt->second == EBhEnable)
{
return true;
}
}
warning(line, "extension is being used", GetExtensionNameString(extension)); warning(line, "extension is being used", GetExtensionNameString(extension));
return true; return true;
} }
...@@ -4233,47 +4276,44 @@ TLayoutQualifier TParseContext::parseLayoutQualifier(const TString &qualifierTyp ...@@ -4233,47 +4276,44 @@ TLayoutQualifier TParseContext::parseLayoutQualifier(const TString &qualifierTyp
checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310); checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
qualifier.imageInternalFormat = EiifR32UI; qualifier.imageInternalFormat = EiifR32UI;
} }
else if (qualifierType == "points" && isExtensionEnabled(TExtension::OES_geometry_shader) && else if (qualifierType == "points" && mShaderType == GL_GEOMETRY_SHADER_OES &&
mShaderType == GL_GEOMETRY_SHADER_OES) checkCanUseExtension(qualifierTypeLine, TExtension::OES_geometry_shader))
{ {
checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310); checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
qualifier.primitiveType = EptPoints; qualifier.primitiveType = EptPoints;
} }
else if (qualifierType == "lines" && isExtensionEnabled(TExtension::OES_geometry_shader) && else if (qualifierType == "lines" && mShaderType == GL_GEOMETRY_SHADER_OES &&
mShaderType == GL_GEOMETRY_SHADER_OES) checkCanUseExtension(qualifierTypeLine, TExtension::OES_geometry_shader))
{ {
checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310); checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
qualifier.primitiveType = EptLines; qualifier.primitiveType = EptLines;
} }
else if (qualifierType == "lines_adjacency" && else if (qualifierType == "lines_adjacency" && mShaderType == GL_GEOMETRY_SHADER_OES &&
isExtensionEnabled(TExtension::OES_geometry_shader) && checkCanUseExtension(qualifierTypeLine, TExtension::OES_geometry_shader))
mShaderType == GL_GEOMETRY_SHADER_OES)
{ {
checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310); checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
qualifier.primitiveType = EptLinesAdjacency; qualifier.primitiveType = EptLinesAdjacency;
} }
else if (qualifierType == "triangles" && isExtensionEnabled(TExtension::OES_geometry_shader) && else if (qualifierType == "triangles" && mShaderType == GL_GEOMETRY_SHADER_OES &&
mShaderType == GL_GEOMETRY_SHADER_OES) checkCanUseExtension(qualifierTypeLine, TExtension::OES_geometry_shader))
{ {
checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310); checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
qualifier.primitiveType = EptTriangles; qualifier.primitiveType = EptTriangles;
} }
else if (qualifierType == "triangles_adjacency" && else if (qualifierType == "triangles_adjacency" && mShaderType == GL_GEOMETRY_SHADER_OES &&
isExtensionEnabled(TExtension::OES_geometry_shader) && checkCanUseExtension(qualifierTypeLine, TExtension::OES_geometry_shader))
mShaderType == GL_GEOMETRY_SHADER_OES)
{ {
checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310); checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
qualifier.primitiveType = EptTrianglesAdjacency; qualifier.primitiveType = EptTrianglesAdjacency;
} }
else if (qualifierType == "line_strip" && isExtensionEnabled(TExtension::OES_geometry_shader) && else if (qualifierType == "line_strip" && mShaderType == GL_GEOMETRY_SHADER_OES &&
mShaderType == GL_GEOMETRY_SHADER_OES) checkCanUseExtension(qualifierTypeLine, TExtension::OES_geometry_shader))
{ {
checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310); checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
qualifier.primitiveType = EptLineStrip; qualifier.primitiveType = EptLineStrip;
} }
else if (qualifierType == "triangle_strip" && else if (qualifierType == "triangle_strip" && mShaderType == GL_GEOMETRY_SHADER_OES &&
isExtensionEnabled(TExtension::OES_geometry_shader) && checkCanUseExtension(qualifierTypeLine, TExtension::OES_geometry_shader))
mShaderType == GL_GEOMETRY_SHADER_OES)
{ {
checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310); checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
qualifier.primitiveType = EptTriangleStrip; qualifier.primitiveType = EptTriangleStrip;
...@@ -4429,15 +4469,13 @@ TLayoutQualifier TParseContext::parseLayoutQualifier(const TString &qualifierTyp ...@@ -4429,15 +4469,13 @@ TLayoutQualifier TParseContext::parseLayoutQualifier(const TString &qualifierTyp
{ {
parseNumViews(intValue, intValueLine, intValueString, &qualifier.numViews); parseNumViews(intValue, intValueLine, intValueString, &qualifier.numViews);
} }
else if (qualifierType == "invocations" && else if (qualifierType == "invocations" && mShaderType == GL_GEOMETRY_SHADER_OES &&
isExtensionEnabled(TExtension::OES_geometry_shader) && checkCanUseExtension(qualifierTypeLine, TExtension::OES_geometry_shader))
mShaderType == GL_GEOMETRY_SHADER_OES)
{ {
parseInvocations(intValue, intValueLine, intValueString, &qualifier.invocations); parseInvocations(intValue, intValueLine, intValueString, &qualifier.invocations);
} }
else if (qualifierType == "max_vertices" && else if (qualifierType == "max_vertices" && mShaderType == GL_GEOMETRY_SHADER_OES &&
isExtensionEnabled(TExtension::OES_geometry_shader) && checkCanUseExtension(qualifierTypeLine, TExtension::OES_geometry_shader))
mShaderType == GL_GEOMETRY_SHADER_OES)
{ {
parseMaxVertices(intValue, intValueLine, intValueString, &qualifier.maxVertices); parseMaxVertices(intValue, intValueLine, intValueString, &qualifier.maxVertices);
} }
......
...@@ -91,13 +91,12 @@ class GeometryShaderTest : public ShaderCompileTreeTest ...@@ -91,13 +91,12 @@ class GeometryShaderTest : public ShaderCompileTreeTest
return sstream.str(); return sstream.str();
} }
const std::string kVersion = "#version 310 es\n";
const std::array<std::string, 2> kExtensionStrings = {
{"#extension GL_OES_geometry_shader", "#extension GL_EXT_geometry_shader"}};
const std::string kHeader = const std::string kHeader =
"#version 310 es\n" "#version 310 es\n"
"#extension GL_OES_geometry_shader : require\n"; "#extension GL_OES_geometry_shader : require\n";
const std::string kEmptyBody =
"void main()\n"
"{\n"
"}\n";
const std::string kInputLayout = "layout (points) in;\n"; const std::string kInputLayout = "layout (points) in;\n";
const std::string kOutputLayout = "layout (points, max_vertices = 1) out;\n"; const std::string kOutputLayout = "layout (points, max_vertices = 1) out;\n";
...@@ -108,6 +107,29 @@ class GeometryShaderTest : public ShaderCompileTreeTest ...@@ -108,6 +107,29 @@ class GeometryShaderTest : public ShaderCompileTreeTest
{"lines_adjacency", 4}, {"lines_adjacency", 4},
{"triangles", 3}, {"triangles", 3},
{"triangles_adjacency", 6}}; {"triangles_adjacency", 6}};
const std::string kEmptyBody =
"void main()\n"
"{\n"
"}\n";
const std::string kShaderBody =
R"(layout(triangles, invocations = 2) in;
layout(triangle_strip, max_vertices = 3) out;
in vec4 i_color[];
out vec4 o_color;
void main()
{
int maxValue = gl_MaxGeometryInputComponents;
for (int i = 0; i < i_color.length(); i++)
{
gl_Position = gl_in[i].gl_Position;
o_color = i_color[i];
gl_PrimitiveID = gl_PrimitiveIDIn;
gl_Layer = gl_InvocationID;
EmitVertex();
}
EndPrimitive();
})";
}; };
class GeometryShaderOutputCodeTest : public MatchOutputCodeTest class GeometryShaderOutputCodeTest : public MatchOutputCodeTest
...@@ -1564,3 +1586,57 @@ TEST_F(GeometryShaderOutputCodeTest, ValidateGLInMembersInOutputShaderString) ...@@ -1564,3 +1586,57 @@ TEST_F(GeometryShaderOutputCodeTest, ValidateGLInMembersInOutputShaderString)
compile(shaderString2); compile(shaderString2);
EXPECT_TRUE(foundInESSLCode("].gl_Position")); EXPECT_TRUE(foundInESSLCode("].gl_Position"));
} }
// Verify that Geometry Shaders are supported in GLSL ES version 310 with EXT_geometry_shader
// enabled.
TEST_F(GeometryShaderTest, Version310WithEXTExtension)
{
std::ostringstream stream;
const std::string &kEXTExtensionString = kExtensionStrings[1];
ASSERT_TRUE(kEXTExtensionString == "#extension GL_EXT_geometry_shader");
stream << kVersion << kEXTExtensionString << " : require\n" << kShaderBody;
if (!compile(stream.str()))
{
FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
}
}
// Verify that Geometry Shaders are supported in GLSL ES version 310 with mixed using
// "EXT_geometry_shader" and "OES_geometry_shader" extension strings.
TEST_F(GeometryShaderTest, MixedUseOESAndEXTExtension)
{
const std::array<std::string, 3> kExtensionBehaviors = {{"require", "disable", "warn"}};
ASSERT_TRUE(kExtensionStrings.size() == 2u);
for (const std::string &extensionBehavior1 : kExtensionBehaviors)
{
for (const std::string &extensionBehavior2 : kExtensionBehaviors)
{
for (size_t i = 0; i < 2u; ++i)
{
std::ostringstream stream;
stream << kVersion << kExtensionStrings[i] << " : " << extensionBehavior1 << "\n"
<< kExtensionStrings[1 - i] << " : " << extensionBehavior2 << "\n"
<< kShaderBody;
bool shouldCompile =
extensionBehavior1 != "disable" || extensionBehavior2 != "disable";
if (shouldCompile != compile(stream.str()))
{
if (shouldCompile)
{
FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
}
else
{
FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
}
}
}
}
}
}
\ No newline at end of file
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