{
using tcu::TestLog;
+using namespace glu;
+
+struct ShaderVariants
+{
+ GLSLVersion minimum_supported_version;
+ const char* vertex_precision;
+ const char* vertex_body;
+ const char* frag_precision;
+ const char* frag_body;
+ bool should_link;
+};
class ShaderUniformInitializeGlobalCase : public TestCase
{
public:
ShaderUniformInitializeGlobalCase(Context& context, const char* name, const char* description,
- glu::GLSLVersion glslVersion)
+ GLSLVersion glslVersion)
: TestCase(context, name, description), m_glslVersion(glslVersion)
{
}
"void main(void) { }\n";
std::map<std::string, std::string> args;
- args["VERSION_DECL"] = glu::getGLSLVersionDeclaration(m_glslVersion);
+ args["VERSION_DECL"] = getGLSLVersionDeclaration(m_glslVersion);
std::string vertex_code = tcu::StringTemplate(vertex_source_template).specialize(args);
std::string fragment_code = tcu::StringTemplate(fragment_source_template).specialize(args);
// Setup program.
- glu::ShaderProgram program(m_context.getRenderContext(),
- glu::makeVtxFragSources(vertex_code.c_str(), fragment_code.c_str()));
+ ShaderProgram program(m_context.getRenderContext(),
+ makeVtxFragSources(vertex_code.c_str(), fragment_code.c_str()));
// GLSL ES does not allow initialization of global variables with non-constant
// expressions, but GLSL does.
// Check that either compilation or linking fails for ES, and that everything
// succeeds for GL.
- bool vertexOk = program.getShaderInfo(glu::SHADERTYPE_VERTEX).compileOk;
- bool fragmentOk = program.getShaderInfo(glu::SHADERTYPE_FRAGMENT).compileOk;
+ bool vertexOk = program.getShaderInfo(SHADERTYPE_VERTEX).compileOk;
+ bool fragmentOk = program.getShaderInfo(SHADERTYPE_FRAGMENT).compileOk;
bool linkOk = program.getProgramInfo().linkOk;
- if (glu::glslVersionIsES(m_glslVersion))
+ if (glslVersionIsES(m_glslVersion))
{
if (vertexOk && fragmentOk && linkOk)
result = QP_TEST_RESULT_FAIL;
}
protected:
- glu::GLSLVersion m_glslVersion;
+ GLSLVersion m_glslVersion;
};
class ShaderUniformPrecisionLinkCase : public TestCase
{
public:
ShaderUniformPrecisionLinkCase(Context& context, const char* name, const char* description,
- glu::GLSLVersion glslVersion)
- : TestCase(context, name, description), m_glslVersion(glslVersion)
+ const ShaderVariants* shaderVariants, unsigned int shaderVariantsCount,
+ GLSLVersion glslVersion)
+ : TestCase(context, name, description)
+ , m_glslVersion(glslVersion)
+ , m_shaderVariants(shaderVariants)
+ , m_shaderVariantsCount(shaderVariantsCount)
{
}
"\n"
"void main(void) { ${BODY} }\n";
- static const struct
- {
- glu::GLSLVersion minimum_supported_version;
- const char* vertex_precision;
- const char* vertex_body;
- const char* frag_precision;
- const char* frag_body;
- bool should_link;
- } shader_variants[] = {
- /* Use highp on both stages. Check variations of:
- * - of implicit and explicit precision qualifiers
- * - used and unused variables
- * These variants should pass since the precision qualifiers match.
- *
- * These variants require highp to be supported, so will not be run for GLSL_VERSION_100_ES.
- */
- { glu::GLSL_VERSION_300_ES, "", "gl_Position = vec4(1.0, 1.0, 1.0, 1.0);", "highp", "result = value;",
- true },
- { glu::GLSL_VERSION_300_ES, "", "gl_Position = vec4(1.0, 1.0, 1.0, 1.0) + value;", "highp",
- "result = value;", true },
- { glu::GLSL_VERSION_300_ES, "highp", "gl_Position = vec4(1.0, 1.0, 1.0, 1.0);", "highp", "result = value;",
- true },
- { glu::GLSL_VERSION_300_ES, "highp", "gl_Position = vec4(1.0, 1.0, 1.0, 1.0) + value;", "highp",
- "result = value;", true },
-
- /* Use highp in vertex shaders, mediump in fragment shaders. Check variations as above.
- * These variants should fail since the precision qualifiers do not match, and matching is done
- * based on declaration - independent of static use.
- */
- { glu::GLSL_VERSION_100_ES, "", "gl_Position = vec4(1.0, 1.0, 1.0, 1.0);", "mediump", "result = value;",
- false },
- { glu::GLSL_VERSION_100_ES, "", "gl_Position = vec4(1.0, 1.0, 1.0, 1.0) + value;", "mediump",
- "result = value;", false },
- { glu::GLSL_VERSION_100_ES, "highp", "gl_Position = vec4(1.0, 1.0, 1.0, 1.0);", "mediump",
- "result = value;", false },
- { glu::GLSL_VERSION_100_ES, "highp", "gl_Position = vec4(1.0, 1.0, 1.0, 1.0) + value;", "mediump",
- "result = value;", false },
-
- /* Use mediump in vertex shaders, highp in fragment shaders. Check variations as above.
- * These variations should fail for the same reason as above.
- */
- { glu::GLSL_VERSION_300_ES, "mediump", "gl_Position = vec4(1.0, 1.0, 1.0, 1.0);", "highp",
- "result = vec4(1.0, 1.0, 1.0, 1.0);", false },
- { glu::GLSL_VERSION_300_ES, "mediump", "gl_Position = vec4(1.0, 1.0, 1.0, 1.0);", "highp",
- "result = value;", false },
- };
-
- for (int i = 0; i < DE_LENGTH_OF_ARRAY(shader_variants); i++)
+ for (unsigned int i = 0; i < m_shaderVariantsCount; i++)
{
std::map<std::string, std::string> args;
- if (m_glslVersion <= shader_variants[i].minimum_supported_version)
+ if (m_glslVersion <= m_shaderVariants[i].minimum_supported_version)
{
continue;
}
- args["VERSION_DECL"] = glu::getGLSLVersionDeclaration(m_glslVersion);
- args["PREC_QUALIFIER"] = shader_variants[i].vertex_precision;
- args["BODY"] = shader_variants[i].vertex_body;
+ args["VERSION_DECL"] = getGLSLVersionDeclaration(m_glslVersion);
+ args["PREC_QUALIFIER"] = m_shaderVariants[i].vertex_precision;
+ args["BODY"] = m_shaderVariants[i].vertex_body;
std::string vcode = tcu::StringTemplate(vertex_source_template).specialize(args);
- args["PREC_QUALIFIER"] = shader_variants[i].frag_precision;
- args["BODY"] = shader_variants[i].frag_body;
+ args["PREC_QUALIFIER"] = m_shaderVariants[i].frag_precision;
+ args["BODY"] = m_shaderVariants[i].frag_body;
std::string fcode = tcu::StringTemplate(fragment_source_template).specialize(args);
// Setup program.
- glu::ShaderProgram program(m_context.getRenderContext(),
- glu::makeVtxFragSources(vcode.c_str(), fcode.c_str()));
+ ShaderProgram program(m_context.getRenderContext(), makeVtxFragSources(vcode.c_str(), fcode.c_str()));
// Check that compile/link results are what we expect.
- bool vertexOk = program.getShaderInfo(glu::SHADERTYPE_VERTEX).compileOk;
- bool fragmentOk = program.getShaderInfo(glu::SHADERTYPE_FRAGMENT).compileOk;
+ bool vertexOk = program.getShaderInfo(SHADERTYPE_VERTEX).compileOk;
+ bool fragmentOk = program.getShaderInfo(SHADERTYPE_FRAGMENT).compileOk;
bool linkOk = program.getProgramInfo().linkOk;
const char* failReason = DE_NULL;
{
failReason = "expected shaders to compile, but failed.";
}
- else if (shader_variants[i].should_link && !linkOk)
+ else if (m_shaderVariants[i].should_link && !linkOk)
{
failReason = "expected shaders to link, but failed.";
}
- else if (!shader_variants[i].should_link && linkOk)
+ else if (!m_shaderVariants[i].should_link && linkOk)
{
failReason = "expected shaders to fail linking, but succeeded.";
}
}
protected:
- glu::GLSLVersion m_glslVersion;
+ GLSLVersion m_glslVersion;
+ const ShaderVariants* m_shaderVariants;
+ unsigned int m_shaderVariantsCount;
};
class ShaderConstantSequenceExpressionCase : public TestCase
{
public:
ShaderConstantSequenceExpressionCase(Context& context, const char* name, const char* description,
- glu::GLSLVersion glslVersion)
+ GLSLVersion glslVersion)
: TestCase(context, name, description), m_glslVersion(glslVersion)
{
}
"void main(void) { }\n";
std::map<std::string, std::string> args;
- args["VERSION_DECL"] = glu::getGLSLVersionDeclaration(m_glslVersion);
+ args["VERSION_DECL"] = getGLSLVersionDeclaration(m_glslVersion);
std::string vertex_code = tcu::StringTemplate(vertex_source_template).specialize(args);
std::string fragment_code = tcu::StringTemplate(fragment_source_template).specialize(args);
// Setup program.
- glu::ShaderProgram program(m_context.getRenderContext(),
- glu::makeVtxFragSources(vertex_code.c_str(), fragment_code.c_str()));
+ ShaderProgram program(m_context.getRenderContext(),
+ makeVtxFragSources(vertex_code.c_str(), fragment_code.c_str()));
// GLSL does not allow the sequence operator in a constant expression
// Check that either compilation or linking fails
- bool vertexOk = program.getShaderInfo(glu::SHADERTYPE_VERTEX).compileOk;
- bool fragmentOk = program.getShaderInfo(glu::SHADERTYPE_FRAGMENT).compileOk;
+ bool vertexOk = program.getShaderInfo(SHADERTYPE_VERTEX).compileOk;
+ bool fragmentOk = program.getShaderInfo(SHADERTYPE_FRAGMENT).compileOk;
bool linkOk = program.getProgramInfo().linkOk;
- bool run_test_es = (glu::glslVersionIsES(m_glslVersion) && m_glslVersion > glu::GLSL_VERSION_100_ES);
- bool run_test_desktop = (m_glslVersion > glu::GLSL_VERSION_420);
+ bool run_test_es = (glslVersionIsES(m_glslVersion) && m_glslVersion > GLSL_VERSION_100_ES);
+ bool run_test_desktop = (m_glslVersion > GLSL_VERSION_420);
if (run_test_es || run_test_desktop)
{
if (vertexOk && fragmentOk && linkOk)
}
protected:
- glu::GLSLVersion m_glslVersion;
+ GLSLVersion m_glslVersion;
};
-ShaderNegativeTests::ShaderNegativeTests(Context& context, glu::GLSLVersion glslVersion)
+ShaderNegativeTests::ShaderNegativeTests(Context& context, GLSLVersion glslVersion)
: TestCaseGroup(context, "negative", "Shader Negative tests"), m_glslVersion(glslVersion)
{
// empty
addChild(new ShaderUniformInitializeGlobalCase(
m_context, "initialize", "Verify initialization of globals with non-constant expressions fails on ES.",
m_glslVersion));
-#if 0
- /*
- * This test is disabled for now since not all existing implementations follow these rules
- * and enforcing them now would break existing applications, which is unacceptable.
- *
- * See https://cvs.khronos.org/bugzilla/show_bug.cgi?id=13922 for further details.
- */
- addChild(new ShaderUniformPrecisionLinkCase(m_context, "uniform_precision_matching",
- "Verify that linking fails if precision qualifiers on default uniform do not match",
- m_glslVersion));
-#endif
+
addChild(new ShaderConstantSequenceExpressionCase(
m_context, "constant_sequence", "Verify that the sequence operator cannot be used as a constant expression.",
m_glslVersion));
+
+ if (isGLSLVersionSupported(m_context.getRenderContext().getType(), GLSL_VERSION_320_ES))
+ {
+ static const ShaderVariants used_variables_variants[] = {
+ /* These variants should pass since the precision qualifiers match.
+ * These variants require highp to be supported, so will not be run for GLSL_VERSION_100_ES.
+ */
+ { GLSL_VERSION_300_ES, "", "gl_Position = vec4(1.0) + value;", "highp", "result = value;", true },
+ { GLSL_VERSION_300_ES, "highp", "gl_Position = vec4(1.0) + value;", "highp", "result = value;", true },
+
+ /* Use highp in vertex shaders, mediump in fragment shaders. Check variations as above.
+ * These variants should fail since the precision qualifiers do not match, and matching is done
+ * based on declaration - independent of static use.
+ */
+ { GLSL_VERSION_100_ES, "", "gl_Position = vec4(1.0) + value;", "mediump", "result = value;", false },
+ { GLSL_VERSION_100_ES, "highp", "gl_Position = vec4(1.0) + value;", "mediump", "result = value;", false },
+ };
+ unsigned int used_variables_variants_count = sizeof(used_variables_variants) / sizeof(ShaderVariants);
+
+ static const ShaderVariants unused_variables_variants[] = {
+ /* These variants should pass since the precision qualifiers match.
+ * These variants require highp to be supported, so will not be run for GLSL_VERSION_100_ES.
+ */
+ { GLSL_VERSION_300_ES, "", "gl_Position = vec4(1.0);", "highp", "result = value;", true },
+ { GLSL_VERSION_300_ES, "highp", "gl_Position = vec4(1.0);", "highp", "result = value;", true },
+
+ /* Use highp in vertex shaders, mediump in fragment shaders. Check variations as above.
+ * These variants should fail since the precision qualifiers do not match, and matching is done
+ * based on declaration - independent of static use.
+ */
+ { GLSL_VERSION_100_ES, "", "gl_Position = vec4(1.0);", "mediump", "result = value;", false },
+ { GLSL_VERSION_100_ES, "highp", "gl_Position = vec4(1.0);", "mediump", "result = value;", false },
+
+ /* Use mediump in vertex shaders, highp in fragment shaders. Check variations as above.
+ * These variations should fail for the same reason as above.
+ */
+ { GLSL_VERSION_300_ES, "mediump", "gl_Position = vec4(1.0);", "highp", "result = vec4(1.0);", false },
+ { GLSL_VERSION_300_ES, "mediump", "gl_Position = vec4(1.0);", "highp", "result = value;", false },
+ };
+ unsigned int unused_variables_variants_count = sizeof(unused_variables_variants) / sizeof(ShaderVariants);
+
+ addChild(new ShaderUniformPrecisionLinkCase(
+ m_context, "used_uniform_precision_matching",
+ "Verify that linking fails if precision qualifiers on default uniform do not match",
+ used_variables_variants, used_variables_variants_count, m_glslVersion));
+
+ addChild(new ShaderUniformPrecisionLinkCase(
+ m_context, "unused_uniform_precision_matching",
+ "Verify that linking fails if precision qualifiers on default not used uniform do not match",
+ unused_variables_variants, unused_variables_variants_count, m_glslVersion));
+ }
}
} // deqp
#include "deRandom.hpp"
#include "deStringUtil.hpp"
#include "glcUniformBlockCase.hpp"
+#include "glwEnums.hpp"
+#include "glwFunctions.hpp"
#include "tcuCommandLine.hpp"
+#include "tcuTestLog.hpp"
namespace deqp
{
int m_numInstances;
};
+class UniformBlockPrecisionMatching : public TestCase
+{
+public:
+ UniformBlockPrecisionMatching(Context& context, glu::GLSLVersion glslVersion)
+ : TestCase(context, "precision_matching", ""), m_glslVersion(glslVersion)
+ {
+ }
+
+ IterateResult iterate(void)
+ {
+ std::string vs1("layout (std140) uniform Data { lowp float x; } myData;\n"
+ "void main() {\n"
+ " gl_Position = vec4(myData.x, 0.0, 0.0, 1.0);\n"
+ "}");
+ std::string fs1("precision highp float;\n"
+ "out vec4 color;\n"
+ "layout (std140) uniform Data { float x; } myData;\n"
+ "void main() {\n"
+ " color = vec4(myData.x);\n"
+ "}");
+
+ std::string vs2("layout (std140) uniform Data { highp int x; mediump int y; } myData;\n"
+ "void main() {\n"
+ " gl_Position = vec4(float(myData.x), 0.0, 0.0, 1.0);\n"
+ "}");
+ std::string fs2("precision highp float;\n"
+ "out vec4 color;\n"
+ "layout (std140) uniform Data { mediump int x; highp int y; } myData;\n"
+ "void main() {\n"
+ " color = vec4(float(myData.y));\n"
+ "}");
+
+ m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
+ if (!Link(vs1, fs1) || !Link(vs2, fs2))
+ m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
+ return STOP;
+ }
+
+ bool Link(const std::string& vs, const std::string& fs)
+ {
+ const glw::Functions& gl = m_context.getRenderContext().getFunctions();
+ const glw::GLuint p = gl.createProgram();
+ const std::string version = glu::getGLSLVersionDeclaration(m_glslVersion);
+
+ static const struct
+ {
+ const char* name;
+ const std::string& body;
+ glw::GLenum type;
+ } shaderDefinition[] = { { "VS", vs, GL_VERTEX_SHADER }, { "FS", fs, GL_FRAGMENT_SHADER } };
+
+ for (unsigned int index = 0; index < 2; ++index)
+ {
+ std::string shaderSource = version + "\n" + shaderDefinition[index].body;
+ const char* shaderSourcePtr = shaderSource.c_str();
+
+ glw::GLuint sh = gl.createShader(shaderDefinition[index].type);
+ gl.attachShader(p, sh);
+ gl.deleteShader(sh);
+ gl.shaderSource(sh, 1, &shaderSourcePtr, NULL);
+ gl.compileShader(sh);
+
+ glw::GLint status;
+ gl.getShaderiv(sh, GL_COMPILE_STATUS, &status);
+ if (status == GL_FALSE)
+ {
+ glw::GLint length;
+ gl.getShaderiv(sh, GL_INFO_LOG_LENGTH, &length);
+ if (length > 0)
+ {
+ std::vector<glw::GLchar> log(length);
+ gl.getShaderInfoLog(sh, length, NULL, &log[0]);
+ m_context.getTestContext().getLog() << tcu::TestLog::Message << shaderDefinition[index].name
+ << " compilation should succed. Info Log:\n"
+ << &log[0] << tcu::TestLog::EndMessage;
+ }
+ gl.deleteProgram(p);
+ return false;
+ }
+ }
+
+ gl.linkProgram(p);
+
+ bool result = true;
+ glw::GLint status;
+ gl.getProgramiv(p, GL_LINK_STATUS, &status);
+ if (status == GL_FALSE)
+ {
+ glw::GLchar log[1024];
+ gl.getProgramInfoLog(p, sizeof(log), NULL, log);
+ m_context.getTestContext().getLog() << tcu::TestLog::Message << "Link operation should succed. Info Log:\n"
+ << log << tcu::TestLog::EndMessage;
+ result = false;
+ }
+
+ gl.deleteProgram(p);
+ return result;
+ }
+
+private:
+ glu::GLSLVersion m_glslVersion;
+};
+
UniformBlockTests::UniformBlockTests(Context& context, glu::GLSLVersion glslVersion)
: TestCaseGroup(context, "uniform_block", "Uniform Block tests"), m_glslVersion(glslVersion)
{
createRandomCaseGroup(randomGroup, m_context, "all_shared_buffer", "All random features, shared buffer",
m_glslVersion, UniformBlockCase::BUFFERMODE_SINGLE, ~0u, 20, 250);
}
+
+ // ubo.common
+ if (glu::isGLSLVersionSupported(m_context.getRenderContext().getType(), glu::GLSL_VERSION_300_ES))
+ {
+ tcu::TestCaseGroup* commonGroup = new tcu::TestCaseGroup(m_testCtx, "common", "Common Uniform Block cases");
+ addChild(commonGroup);
+ commonGroup->addChild(new UniformBlockPrecisionMatching(m_context, m_glslVersion));
+ }
}
} // deqp