Allow dynamic loop cases to fail on GLSL ES 100.
- Add "require full_glsl_es_100_support" to annotate GLSL ES 100 test
that use features that are not within the required subset required by
the GLES 2. Cases with this annotation will report NotSupported if
compile fails, or QualityWarning if linking fails.
- Mark affected tests with "require full_glsl_es_100_support"
Bug: 19678840
Change-Id: If13a79d0221c92da80b1c1fa18f98335f91abfd4
diff --git a/data/gles2/shaders/functions.test b/data/gles2/shaders/functions.test
index 62f8879..83cff96 100644
--- a/data/gles2/shaders/functions.test
+++ b/data/gles2/shaders/functions.test
@@ -2355,6 +2355,8 @@
end
case return_after_loop_sequence
+ require full_glsl_es_100_support
+
values
{
input float in0 = [ -0.5 | 1.5 ];
diff --git a/data/gles2/shaders/scoping.test b/data/gles2/shaders/scoping.test
index 5408704..23e274b 100644
--- a/data/gles2/shaders/scoping.test
+++ b/data/gles2/shaders/scoping.test
@@ -106,6 +106,7 @@
case while_condition_variable_hides_local_variable
version 100 es
+ require full_glsl_es_100_support
values
{
input int in0 = [ 1 | 2 | 3 ];
@@ -160,6 +161,7 @@
case while_condition_variable_hides_global_variable
version 100 es
+ require full_glsl_es_100_support
values
{
input int in0 = [ 1 | 2 | 3 ];
diff --git a/modules/glshared/glsShaderLibrary.cpp b/modules/glshared/glsShaderLibrary.cpp
index a263a44..a97823c 100644
--- a/modules/glshared/glsShaderLibrary.cpp
+++ b/modules/glshared/glsShaderLibrary.cpp
@@ -997,6 +997,12 @@
valueBlock = ShaderCase::CaseRequirement::createLimitRequirement(limitEnum, limitValue);
}
+ else if (m_curTokenStr == "full_glsl_es_100_support")
+ {
+ advanceToken();
+
+ valueBlock = ShaderCase::CaseRequirement::createFullGLSLES100SpecificationRequirement();
+ }
else
parseError(string("invalid requirement value: " + m_curTokenStr));
}
diff --git a/modules/glshared/glsShaderLibraryCase.cpp b/modules/glshared/glsShaderLibraryCase.cpp
index af30141..089d7a6 100644
--- a/modules/glshared/glsShaderLibraryCase.cpp
+++ b/modules/glshared/glsShaderLibraryCase.cpp
@@ -121,6 +121,15 @@
return retVal;
}
+ShaderCase::CaseRequirement ShaderCase::CaseRequirement::createFullGLSLES100SpecificationRequirement (void)
+{
+ CaseRequirement retVal;
+
+ retVal.m_type = REQUIREMENTTYPE_FULL_GLSL_ES_100_SPEC;
+
+ return retVal;
+}
+
void ShaderCase::CaseRequirement::checkRequirements (glu::RenderContext& renderCtx, const glu::ContextInfo& contextInfo)
{
DE_UNREF(renderCtx);
@@ -176,6 +185,12 @@
return;
}
+ case REQUIREMENTTYPE_FULL_GLSL_ES_100_SPEC:
+ {
+ // cannot be queried
+ return;
+ }
+
default:
DE_ASSERT(false);
}
@@ -495,6 +510,19 @@
DE_ASSERT(false);
break;
}
+
+ // sanity of arguments
+
+ if (anyProgramRequiresFullGLSLES100Specification())
+ {
+ // makes only sense in tests where shader compiles
+ DE_ASSERT(m_expectResult == EXPECT_PASS ||
+ m_expectResult == EXPECT_VALIDATION_FAIL ||
+ m_expectResult == EXPECT_BUILD_SUCCESSFUL);
+
+ // only makes sense for ES 100 programs
+ DE_ASSERT(m_targetVersion == glu::GLSL_VERSION_100_ES);
+ }
}
static void setUniformValue (const glw::Functions& gl, const std::vector<deUint32>& pipelinePrograms, const std::string& name, const ShaderCase::Value& val, int arrayNdx, tcu::TestLog& log)
@@ -576,6 +604,17 @@
!m_programs[0].programSources.sources[glu::SHADERTYPE_TESSELLATION_EVALUATION].empty();
}
+bool ShaderCase::anyProgramRequiresFullGLSLES100Specification (void) const
+{
+ for (int programNdx = 0; programNdx < (int)m_programs.size(); ++programNdx)
+ for (int requirementNdx = 0; requirementNdx < (int)m_programs[programNdx].spec.requirements.size(); ++requirementNdx)
+ {
+ if (m_programs[programNdx].spec.requirements[requirementNdx].getType() == CaseRequirement::REQUIREMENTTYPE_FULL_GLSL_ES_100_SPEC)
+ return true;
+ }
+ return false;
+}
+
bool ShaderCase::checkPixels (Surface& surface, int minX, int maxX, int minY, int maxY)
{
TestLog& log = m_testCtx.getLog();
@@ -615,8 +654,8 @@
bool ShaderCase::execute (void)
{
- const float quadSize = 1.0f;
- static const float s_positions[4*4] =
+ const float quadSize = 1.0f;
+ static const float s_positions[4*4] =
{
-quadSize, -quadSize, 0.0f, 1.0f,
-quadSize, +quadSize, 0.0f, 1.0f,
@@ -624,30 +663,31 @@
+quadSize, +quadSize, 0.0f, 1.0f
};
- static const deUint16 s_indices[2*3] =
+ static const deUint16 s_indices[2*3] =
{
0, 1, 2,
1, 3, 2
};
- TestLog& log = m_testCtx.getLog();
- const glw::Functions& gl = m_renderCtx.getFunctions();
+ TestLog& log = m_testCtx.getLog();
+ const glw::Functions& gl = m_renderCtx.getFunctions();
// Compute viewport.
- const tcu::RenderTarget& renderTarget = m_renderCtx.getRenderTarget();
- de::Random rnd (deStringHash(getName()));
- const int width = deMin32(renderTarget.getWidth(), VIEWPORT_WIDTH);
- const int height = deMin32(renderTarget.getHeight(), VIEWPORT_HEIGHT);
- const int viewportX = rnd.getInt(0, renderTarget.getWidth() - width);
- const int viewportY = rnd.getInt(0, renderTarget.getHeight() - height);
- const int numVerticesPerDraw = 4;
- const bool tessellationPresent = isTessellationPresent();
+ const tcu::RenderTarget& renderTarget = m_renderCtx.getRenderTarget();
+ de::Random rnd (deStringHash(getName()));
+ const int width = deMin32(renderTarget.getWidth(), VIEWPORT_WIDTH);
+ const int height = deMin32(renderTarget.getHeight(), VIEWPORT_HEIGHT);
+ const int viewportX = rnd.getInt(0, renderTarget.getWidth() - width);
+ const int viewportY = rnd.getInt(0, renderTarget.getHeight() - height);
+ const int numVerticesPerDraw = 4;
+ const bool tessellationPresent = isTessellationPresent();
+ const bool requiresFullGLSLES100 = anyProgramRequiresFullGLSLES100Specification();
- bool allCompilesOk = true;
- bool allLinksOk = true;
- const char* failReason = DE_NULL;
+ bool allCompilesOk = true;
+ bool allLinksOk = true;
+ const char* failReason = DE_NULL;
- deUint32 vertexProgramID = -1;
+ deUint32 vertexProgramID = -1;
std::vector<deUint32> pipelineProgramIDs;
std::vector<de::SharedPtr<glu::ShaderProgram> > programs;
de::SharedPtr<glu::ProgramPipeline> programPipeline;
@@ -761,9 +801,26 @@
// \todo [2010-06-07 petri] These should be handled in the test case?
log << TestLog::Message << "ERROR: " << failReason << TestLog::EndMessage;
- // If implementation parses shader at link time, report it as quality warning.
- if (m_expectResult == EXPECT_COMPILE_FAIL && allCompilesOk && !allLinksOk)
+ if (requiresFullGLSLES100)
+ {
+ log << TestLog::Message
+ << "Assuming build failure is caused by implementation not supporting full GLSL ES 100 specification, which is not required."
+ << TestLog::EndMessage;
+
+ if (allCompilesOk && !allLinksOk)
+ {
+ // Used features are detectable at compile time. If implementation parses shader
+ // at link time, report it as quality warning.
+ m_testCtx.setTestResult(QP_TEST_RESULT_QUALITY_WARNING, failReason);
+ }
+ else
+ m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Full GLSL ES 100 is not supported");
+ }
+ else if (m_expectResult == EXPECT_COMPILE_FAIL && allCompilesOk && !allLinksOk)
+ {
+ // If implementation parses shader at link time, report it as quality warning.
m_testCtx.setTestResult(QP_TEST_RESULT_QUALITY_WARNING, failReason);
+ }
else
m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, failReason);
return false;
@@ -774,7 +831,7 @@
m_expectResult == EXPECT_COMPILE_LINK_FAIL ||
m_expectResult == EXPECT_LINK_FAIL ||
m_expectResult == EXPECT_BUILD_SUCCESSFUL)
- return (failReason == DE_NULL);
+ return true;
// Setup viewport.
gl.viewport(viewportX, viewportY, width, height);
diff --git a/modules/glshared/glsShaderLibraryCase.hpp b/modules/glshared/glsShaderLibraryCase.hpp
index 8934c98..162ea0f 100644
--- a/modules/glshared/glsShaderLibraryCase.hpp
+++ b/modules/glshared/glsShaderLibraryCase.hpp
@@ -107,19 +107,21 @@
{
REQUIREMENTTYPE_EXTENSION = 0,
REQUIREMENTTYPE_IMPLEMENTATION_LIMIT,
+ REQUIREMENTTYPE_FULL_GLSL_ES_100_SPEC, //!< Full support (as opposed to limited as specified for GLES 2.0 (See GLSL Appendix A)) cannot be queried
REQUIREMENTTYPE_LAST
};
- CaseRequirement (void);
+ CaseRequirement (void);
- static CaseRequirement createAnyExtensionRequirement (const std::vector<std::string>& requirements, deUint32 effectiveShaderStageFlags);
- static CaseRequirement createLimitRequirement (deUint32 enumName, int ref);
- void checkRequirements (glu::RenderContext& renderCtx, const glu::ContextInfo& contextInfo);
+ static CaseRequirement createAnyExtensionRequirement (const std::vector<std::string>& requirements, deUint32 effectiveShaderStageFlags);
+ static CaseRequirement createLimitRequirement (deUint32 enumName, int ref);
+ static CaseRequirement createFullGLSLES100SpecificationRequirement (void);
+ void checkRequirements (glu::RenderContext& renderCtx, const glu::ContextInfo& contextInfo);
- RequirementType getType (void) const { return m_type; };
- std::string getSupportedExtension (void) const { DE_ASSERT(m_type == REQUIREMENTTYPE_EXTENSION); DE_ASSERT(m_supportedExtensionNdx >= 0); return m_extensions[m_supportedExtensionNdx]; }
- deUint32 getAffectedExtensionStageFlags (void) const { DE_ASSERT(m_type == REQUIREMENTTYPE_EXTENSION); return m_effectiveShaderStageFlags; }
+ RequirementType getType (void) const { return m_type; };
+ std::string getSupportedExtension (void) const { DE_ASSERT(m_type == REQUIREMENTTYPE_EXTENSION); DE_ASSERT(m_supportedExtensionNdx >= 0); return m_extensions[m_supportedExtensionNdx]; }
+ deUint32 getAffectedExtensionStageFlags (void) const { DE_ASSERT(m_type == REQUIREMENTTYPE_EXTENSION); return m_effectiveShaderStageFlags; }
private:
RequirementType m_type;
@@ -174,42 +176,43 @@
};
// Methods.
- ShaderCase (tcu::TestContext& testCtx,
- glu::RenderContext& renderCtx,
- const glu::ContextInfo& contextInfo,
- const char* caseName,
- const char* description,
- const ShaderCaseSpecification& specification);
- ShaderCase (tcu::TestContext& testCtx,
- glu::RenderContext& renderCtx,
- const glu::ContextInfo& contextInfo,
- const char* caseName,
- const char* description,
- const PipelineCaseSpecification& specification);
- virtual ~ShaderCase (void);
+ ShaderCase (tcu::TestContext& testCtx,
+ glu::RenderContext& renderCtx,
+ const glu::ContextInfo& contextInfo,
+ const char* caseName,
+ const char* description,
+ const ShaderCaseSpecification& specification);
+ ShaderCase (tcu::TestContext& testCtx,
+ glu::RenderContext& renderCtx,
+ const glu::ContextInfo& contextInfo,
+ const char* caseName,
+ const char* description,
+ const PipelineCaseSpecification& specification);
+ virtual ~ShaderCase (void);
private:
- void init (void);
- bool execute (void);
- IterateResult iterate (void);
+ void init (void);
+ bool execute (void);
+ IterateResult iterate (void);
- ShaderCase (const ShaderCase&); // not allowed!
- ShaderCase& operator= (const ShaderCase&); // not allowed!
+ ShaderCase (const ShaderCase&); // not allowed!
+ ShaderCase& operator= (const ShaderCase&); // not allowed!
- std::string genVertexShader (const ValueBlock& valueBlock) const;
- std::string genFragmentShader (const ValueBlock& valueBlock) const;
- std::string specializeVertexShader (const char* src, const ValueBlock& valueBlock) const;
- std::string specializeFragmentShader (const char* src, const ValueBlock& valueBlock) const;
- void specializeVertexShaders (glu::ProgramSources& dst, const std::vector<std::string>& sources, const ValueBlock& valueBlock, const std::vector<ShaderCase::CaseRequirement>& requirements) const;
- void specializeFragmentShaders (glu::ProgramSources& dst, const std::vector<std::string>& sources, const ValueBlock& valueBlock, const std::vector<ShaderCase::CaseRequirement>& requirements) const;
- void specializeGeometryShaders (glu::ProgramSources& dst, const std::vector<std::string>& sources, const ValueBlock& valueBlock, const std::vector<ShaderCase::CaseRequirement>& requirements) const;
- void specializeTessControlShaders (glu::ProgramSources& dst, const std::vector<std::string>& sources, const ValueBlock& valueBlock, const std::vector<ShaderCase::CaseRequirement>& requirements) const;
- void specializeTessEvalShaders (glu::ProgramSources& dst, const std::vector<std::string>& sources, const ValueBlock& valueBlock, const std::vector<ShaderCase::CaseRequirement>& requirements) const;
- bool isTessellationPresent (void) const;
+ std::string genVertexShader (const ValueBlock& valueBlock) const;
+ std::string genFragmentShader (const ValueBlock& valueBlock) const;
+ std::string specializeVertexShader (const char* src, const ValueBlock& valueBlock) const;
+ std::string specializeFragmentShader (const char* src, const ValueBlock& valueBlock) const;
+ void specializeVertexShaders (glu::ProgramSources& dst, const std::vector<std::string>& sources, const ValueBlock& valueBlock, const std::vector<ShaderCase::CaseRequirement>& requirements) const;
+ void specializeFragmentShaders (glu::ProgramSources& dst, const std::vector<std::string>& sources, const ValueBlock& valueBlock, const std::vector<ShaderCase::CaseRequirement>& requirements) const;
+ void specializeGeometryShaders (glu::ProgramSources& dst, const std::vector<std::string>& sources, const ValueBlock& valueBlock, const std::vector<ShaderCase::CaseRequirement>& requirements) const;
+ void specializeTessControlShaders (glu::ProgramSources& dst, const std::vector<std::string>& sources, const ValueBlock& valueBlock, const std::vector<ShaderCase::CaseRequirement>& requirements) const;
+ void specializeTessEvalShaders (glu::ProgramSources& dst, const std::vector<std::string>& sources, const ValueBlock& valueBlock, const std::vector<ShaderCase::CaseRequirement>& requirements) const;
+ bool isTessellationPresent (void) const;
+ bool anyProgramRequiresFullGLSLES100Specification (void) const;
- void dumpValues (const ValueBlock& valueBlock, int arrayNdx);
+ void dumpValues (const ValueBlock& valueBlock, int arrayNdx);
- bool checkPixels (tcu::Surface& surface, int minX, int maxX, int minY, int maxY);
+ bool checkPixels (tcu::Surface& surface, int minX, int maxX, int minY, int maxY);
struct ProgramObject
{