Commit 624fbdcf by Olli Etuaho Committed by Commit Bot

Refactor CompileProgram utility

Tests often need to call gl functions to set up program related state after glCreateProgram has been called but prior to glLinkProgram is called. Add a callback function to the CompileProgram utility function to fulfill this need. This reduces code duplication considerably in several tests. An alternative way to improve CompileProgram would be to split it into several different utility functions. This might be slightly easier to read, but would also be a larger refactoring and require more checks at the call site. This will make it easier to implement EXT_blend_func_extended tests, which need to bind fragment outputs to different slots. BUG=angleproject:1085 TEST=angle_end2end_tests Change-Id: I3ac8b7bdc21c6a1f14517bc7df0cf6f35abd7612 Reviewed-on: https://chromium-review.googlesource.com/1254062 Commit-Queue: Olli Etuaho <oetuaho@nvidia.com> Reviewed-by: 's avatarCorentin Wallez <cwallez@chromium.org>
parent 079a6bc3
......@@ -74,27 +74,12 @@ TEST_P(BindUniformLocationTest, Basic)
GLint colorBLocation = 10;
GLint colorCLocation = 5;
GLuint vs = CompileShader(GL_VERTEX_SHADER, essl1_shaders::vs::Simple());
GLuint fs = CompileShader(GL_FRAGMENT_SHADER, fsSource);
mProgram = glCreateProgram();
mBindUniformLocation(mProgram, colorALocation, "u_colorA");
mBindUniformLocation(mProgram, colorBLocation, "u_colorB[0]");
mBindUniformLocation(mProgram, colorCLocation, "u_colorC");
glAttachShader(mProgram, vs);
glDeleteShader(vs);
glAttachShader(mProgram, fs);
glDeleteShader(fs);
// Link the mProgram
glLinkProgram(mProgram);
// Check the link status
GLint linked = 0;
glGetProgramiv(mProgram, GL_LINK_STATUS, &linked);
ASSERT_EQ(1, linked);
mProgram = CompileProgram(essl1_shaders::vs::Simple(), fsSource, [&](GLuint program) {
mBindUniformLocation(program, colorALocation, "u_colorA");
mBindUniformLocation(program, colorBLocation, "u_colorB[0]");
mBindUniformLocation(program, colorCLocation, "u_colorC");
});
ASSERT_NE(0u, mProgram);
glUseProgram(mProgram);
......@@ -133,27 +118,12 @@ TEST_P(BindUniformLocationTest, SamplerLocation)
GLint colorBLocation = 10;
GLint samplerLocation = 1;
GLuint vs = CompileShader(GL_VERTEX_SHADER, essl1_shaders::vs::Simple());
GLuint fs = CompileShader(GL_FRAGMENT_SHADER, fsSource);
mProgram = glCreateProgram();
mBindUniformLocation(mProgram, colorALocation, "u_colorA");
mBindUniformLocation(mProgram, colorBLocation, "u_colorB[0]");
mBindUniformLocation(mProgram, samplerLocation, "u_sampler");
glAttachShader(mProgram, vs);
glDeleteShader(vs);
glAttachShader(mProgram, fs);
glDeleteShader(fs);
// Link the mProgram
glLinkProgram(mProgram);
// Check the link status
GLint linked = 0;
glGetProgramiv(mProgram, GL_LINK_STATUS, &linked);
ASSERT_EQ(1, linked);
mProgram = CompileProgram(essl1_shaders::vs::Simple(), fsSource, [&](GLuint program) {
mBindUniformLocation(program, colorALocation, "u_colorA");
mBindUniformLocation(program, colorBLocation, "u_colorB[0]");
mBindUniformLocation(program, samplerLocation, "u_sampler");
});
ASSERT_NE(0u, mProgram);
glUseProgram(mProgram);
......@@ -275,29 +245,15 @@ TEST_P(BindUniformLocationTest, Compositor)
int multiplierLocation = counter++;
int colorCLocation = counter++;
GLuint vs = CompileShader(GL_VERTEX_SHADER, vsSource);
GLuint fs = CompileShader(GL_FRAGMENT_SHADER, fsSource);
mProgram = glCreateProgram();
mBindUniformLocation(mProgram, matrixLocation, "matrix");
mBindUniformLocation(mProgram, colorALocation, "color_a");
mBindUniformLocation(mProgram, colorBLocation, "color_b");
mBindUniformLocation(mProgram, alphaLocation, "alpha");
mBindUniformLocation(mProgram, multiplierLocation, "multiplier");
mBindUniformLocation(mProgram, colorCLocation, "color_c");
glAttachShader(mProgram, vs);
glDeleteShader(vs);
glAttachShader(mProgram, fs);
glDeleteShader(fs);
// Link the mProgram
glLinkProgram(mProgram);
// Check the link status
GLint linked = 0;
glGetProgramiv(mProgram, GL_LINK_STATUS, &linked);
ASSERT_EQ(1, linked);
mProgram = CompileProgram(vsSource, fsSource, [&](GLuint program) {
mBindUniformLocation(program, matrixLocation, "matrix");
mBindUniformLocation(program, colorALocation, "color_a");
mBindUniformLocation(program, colorBLocation, "color_b");
mBindUniformLocation(program, alphaLocation, "alpha");
mBindUniformLocation(program, multiplierLocation, "multiplier");
mBindUniformLocation(program, colorCLocation, "color_c");
});
ASSERT_NE(0u, mProgram);
glUseProgram(mProgram);
......@@ -349,23 +305,15 @@ TEST_P(BindUniformLocationTest, UnusedUniformUpdate)
const GLint nonexistingLocation = 5;
const GLint unboundLocation = 6;
GLuint vs = CompileShader(GL_VERTEX_SHADER, essl1_shaders::vs::Simple());
GLuint fs = CompileShader(GL_FRAGMENT_SHADER, fsSource);
mProgram = CompileProgram(essl1_shaders::vs::Simple(), fsSource, [&](GLuint program) {
mBindUniformLocation(program, colorULocation, "u_colorU");
// The non-existing uniform should behave like existing, but optimized away
// uniform.
mBindUniformLocation(program, nonexistingLocation, "nonexisting");
// Let A and C be assigned automatic locations.
});
ASSERT_NE(0u, mProgram);
mProgram = glCreateProgram();
mBindUniformLocation(mProgram, colorULocation, "u_colorU");
// The non-existing uniform should behave like existing, but optimized away
// uniform.
mBindUniformLocation(mProgram, nonexistingLocation, "nonexisting");
// Let A and C be assigned automatic locations.
glAttachShader(mProgram, vs);
glDeleteShader(vs);
glAttachShader(mProgram, fs);
glDeleteShader(fs);
glLinkProgram(mProgram);
GLint linked = 0;
glGetProgramiv(mProgram, GL_LINK_STATUS, &linked);
ASSERT_EQ(1, linked);
glUseProgram(mProgram);
// No errors on bound locations, since caller does not know
......@@ -437,22 +385,11 @@ TEST_P(BindUniformLocationTest, UseSamplerWhenUnusedUniforms)
const GLuint texLocation = 54;
GLuint vs = CompileShader(GL_VERTEX_SHADER, essl1_shaders::vs::Simple());
GLuint fs = CompileShader(GL_FRAGMENT_SHADER, fsSource);
mProgram = glCreateProgram();
mBindUniformLocation(mProgram, texLocation, "tex");
glAttachShader(mProgram, vs);
glDeleteShader(vs);
glAttachShader(mProgram, fs);
glDeleteShader(fs);
glLinkProgram(mProgram);
mProgram = CompileProgram(essl1_shaders::vs::Simple(), fsSource, [&](GLuint program) {
mBindUniformLocation(program, texLocation, "tex");
});
ASSERT_NE(0u, mProgram);
GLint linked = 0;
glGetProgramiv(mProgram, GL_LINK_STATUS, &linked);
EXPECT_NE(0, linked);
glUseProgram(mProgram);
glUniform1i(texLocation, 0);
EXPECT_GL_NO_ERROR();
......@@ -477,23 +414,12 @@ TEST_P(BindUniformLocationTest, SameLocationForUsedAndUnusedUniform)
const GLuint location = 54;
GLuint vs = CompileShader(GL_VERTEX_SHADER, essl1_shaders::vs::Zero());
GLuint fs = CompileShader(GL_FRAGMENT_SHADER, fsSource);
mProgram = glCreateProgram();
mBindUniformLocation(mProgram, location, "a");
mBindUniformLocation(mProgram, location, "b");
mProgram = CompileProgram(essl1_shaders::vs::Zero(), fsSource, [&](GLuint program) {
mBindUniformLocation(program, location, "a");
mBindUniformLocation(program, location, "b");
});
ASSERT_NE(0u, mProgram);
glAttachShader(mProgram, vs);
glDeleteShader(vs);
glAttachShader(mProgram, fs);
glDeleteShader(fs);
glLinkProgram(mProgram);
GLint linked = GL_FALSE;
glGetProgramiv(mProgram, GL_LINK_STATUS, &linked);
ASSERT_GL_TRUE(linked);
glUseProgram(mProgram);
glUniform4f(location, 0.0, 1.0, 0.0, 1.0);
EXPECT_GL_NO_ERROR();
......@@ -504,20 +430,14 @@ class BindUniformLocationES31Test : public BindUniformLocationTest
protected:
BindUniformLocationES31Test() : BindUniformLocationTest() {}
void linkProgramWithUniformLocation(GLuint vs,
GLuint fs,
void linkProgramWithUniformLocation(const std::string &vs,
const std::string &fs,
const char *uniformName,
GLint uniformLocation)
{
mProgram = glCreateProgram();
mBindUniformLocation(mProgram, uniformLocation, uniformName);
glAttachShader(mProgram, vs);
glDeleteShader(vs);
glAttachShader(mProgram, fs);
glDeleteShader(fs);
glLinkProgram(mProgram);
mProgram = CompileProgram(vs, fs, [&](GLuint program) {
mBindUniformLocation(program, uniformLocation, uniformName);
});
}
};
......@@ -538,11 +458,7 @@ TEST_P(BindUniformLocationES31Test, ConsistentWithLocationLayoutQualifier)
const GLuint texLocation = 2;
GLuint vs = CompileShader(GL_VERTEX_SHADER, essl31_shaders::vs::Zero());
EXPECT_NE(0u, vs);
GLuint fs = CompileShader(GL_FRAGMENT_SHADER, fsSource);
EXPECT_NE(0u, fs);
linkProgramWithUniformLocation(vs, fs, "tex", texLocation);
linkProgramWithUniformLocation(essl31_shaders::vs::Zero(), fsSource, "tex", texLocation);
GLint linked = GL_FALSE;
glGetProgramiv(mProgram, GL_LINK_STATUS, &linked);
......@@ -573,11 +489,7 @@ TEST_P(BindUniformLocationES31Test, LocationLayoutQualifierOverridesAPIBinding)
const GLuint shaderTexLocation = 2;
const GLuint texLocation = 3;
GLuint vs = CompileShader(GL_VERTEX_SHADER, essl31_shaders::vs::Zero());
EXPECT_NE(0u, vs);
GLuint fs = CompileShader(GL_FRAGMENT_SHADER, fsSource);
EXPECT_NE(0u, fs);
linkProgramWithUniformLocation(vs, fs, "tex", texLocation);
linkProgramWithUniformLocation(essl31_shaders::vs::Zero(), fsSource, "tex", texLocation);
GLint linked = GL_FALSE;
glGetProgramiv(mProgram, GL_LINK_STATUS, &linked);
......@@ -610,11 +522,7 @@ TEST_P(BindUniformLocationES31Test, LocationLayoutQualifierConflictsWithAPIBindi
const GLuint tex2Location = 2;
GLuint vs = CompileShader(GL_VERTEX_SHADER, essl31_shaders::vs::Zero());
EXPECT_NE(0u, vs);
GLuint fs = CompileShader(GL_FRAGMENT_SHADER, fsSource);
EXPECT_NE(0u, fs);
linkProgramWithUniformLocation(vs, fs, "tex2", tex2Location);
linkProgramWithUniformLocation(essl31_shaders::vs::Zero(), fsSource, "tex2", tex2Location);
GLint linked = GL_FALSE;
glGetProgramiv(mProgram, GL_LINK_STATUS, &linked);
......@@ -638,11 +546,8 @@ TEST_P(BindUniformLocationES31Test, ArrayOfArrays)
const GLuint location = 8;
GLuint vs = CompileShader(GL_VERTEX_SHADER, essl31_shaders::vs::Simple());
EXPECT_NE(0u, vs);
GLuint fs = CompileShader(GL_FRAGMENT_SHADER, fsSource);
EXPECT_NE(0u, fs);
linkProgramWithUniformLocation(vs, fs, "sourceColor[1]", location);
linkProgramWithUniformLocation(essl31_shaders::vs::Simple(), fsSource, "sourceColor[1]",
location);
GLint linked = GL_FALSE;
glGetProgramiv(mProgram, GL_LINK_STATUS, &linked);
......
......@@ -985,21 +985,10 @@ TEST_P(VertexAttributeTest, DisabledAttribArrays)
for (GLint colorIndex = 0; colorIndex < maxVertexAttribs; ++colorIndex)
{
GLuint vs = CompileShader(GL_VERTEX_SHADER, vsSource);
ASSERT_NE(0u, vs);
GLuint fs = CompileShader(GL_FRAGMENT_SHADER, fsSource);
ASSERT_NE(0u, fs);
GLuint program = glCreateProgram();
glBindAttribLocation(program, colorIndex, "a_color");
glAttachShader(program, vs);
glDeleteShader(vs);
glAttachShader(program, fs);
glDeleteShader(fs);
ASSERT_TRUE(LinkAttachedProgram(program));
GLuint program = CompileProgram(vsSource, fsSource, [&](GLuint program) {
glBindAttribLocation(program, colorIndex, "a_color");
});
ASSERT_NE(0u, program);
drawQuad(program, "a_position", 0.5f);
ASSERT_GL_NO_ERROR();
......
......@@ -116,24 +116,11 @@ GLuint CheckLinkStatusAndReturnProgram(GLuint program, bool outputErrorMessages)
return program;
}
GLuint CompileProgramWithTransformFeedback(
const std::string &vsSource,
const std::string &fsSource,
const std::vector<std::string> &transformFeedbackVaryings,
GLenum bufferMode)
static GLuint CompileProgramInternal(const std::string &vsSource,
const std::string &gsSource,
const std::string &fsSource,
const std::function<void(GLuint)> &preLinkCallback)
{
return CompileProgramWithGSAndTransformFeedback(vsSource, "", fsSource,
transformFeedbackVaryings, bufferMode);
}
static GLuint CompileAndLinkProgram(const std::string &vsSource,
const std::string &gsSource,
const std::string &fsSource,
const std::vector<std::string> &transformFeedbackVaryings,
GLenum bufferMode)
{
GLuint program = glCreateProgram();
GLuint vs = CompileShader(GL_VERTEX_SHADER, vsSource);
GLuint fs = CompileShader(GL_FRAGMENT_SHADER, fsSource);
......@@ -141,19 +128,22 @@ static GLuint CompileAndLinkProgram(const std::string &vsSource,
{
glDeleteShader(fs);
glDeleteShader(vs);
glDeleteProgram(program);
return 0;
}
GLuint program = glCreateProgram();
glAttachShader(program, vs);
glDeleteShader(vs);
glAttachShader(program, fs);
glDeleteShader(fs);
GLuint gs = 0;
if (!gsSource.empty())
{
GLuint gs = CompileShader(GL_GEOMETRY_SHADER_EXT, gsSource);
gs = CompileShader(GL_GEOMETRY_SHADER_EXT, gsSource);
if (gs == 0)
{
glDeleteShader(vs);
......@@ -166,52 +156,58 @@ static GLuint CompileAndLinkProgram(const std::string &vsSource,
glDeleteShader(gs);
}
if (transformFeedbackVaryings.size() > 0)
if (preLinkCallback)
{
std::vector<const char *> constCharTFVaryings;
for (const std::string &transformFeedbackVarying : transformFeedbackVaryings)
{
constCharTFVaryings.push_back(transformFeedbackVarying.c_str());
}
glTransformFeedbackVaryings(program, static_cast<GLsizei>(transformFeedbackVaryings.size()),
&constCharTFVaryings[0], bufferMode);
preLinkCallback(program);
}
glLinkProgram(program);
return program;
return CheckLinkStatusAndReturnProgram(program, true);
}
GLuint CompileProgramWithGSAndTransformFeedback(
GLuint CompileProgramWithTransformFeedback(
const std::string &vsSource,
const std::string &gsSource,
const std::string &fsSource,
const std::vector<std::string> &transformFeedbackVaryings,
GLenum bufferMode)
{
GLuint program =
CompileAndLinkProgram(vsSource, gsSource, fsSource, transformFeedbackVaryings, bufferMode);
if (program == 0)
{
return 0;
}
return CheckLinkStatusAndReturnProgram(program, true);
auto preLink = [&](GLuint program) {
if (transformFeedbackVaryings.size() > 0)
{
std::vector<const char *> constCharTFVaryings;
for (const std::string &transformFeedbackVarying : transformFeedbackVaryings)
{
constCharTFVaryings.push_back(transformFeedbackVarying.c_str());
}
glTransformFeedbackVaryings(program,
static_cast<GLsizei>(transformFeedbackVaryings.size()),
&constCharTFVaryings[0], bufferMode);
}
};
return CompileProgramInternal(vsSource, "", fsSource, preLink);
}
GLuint CompileProgram(const std::string &vsSource, const std::string &fsSource)
{
return CompileProgramWithGS(vsSource, "", fsSource);
return CompileProgramInternal(vsSource, "", fsSource, nullptr);
}
GLuint CompileProgram(const std::string &vsSource,
const std::string &fsSource,
const std::function<void(GLuint)> &preLinkCallback)
{
return CompileProgramInternal(vsSource, "", fsSource, preLinkCallback);
}
GLuint CompileProgramWithGS(const std::string &vsSource,
const std::string &gsSource,
const std::string &fsSource)
{
std::vector<std::string> emptyVector;
return CompileProgramWithGSAndTransformFeedback(vsSource, gsSource, fsSource, emptyVector,
GL_NONE);
return CompileProgramInternal(vsSource, gsSource, fsSource, nullptr);
}
GLuint CompileProgramFromFiles(const std::string &vsPath, const std::string &fsPath)
......
......@@ -15,6 +15,7 @@
#include <EGL/egl.h>
#include <EGL/eglext.h>
#include <functional>
#include <string>
#include <vector>
......@@ -27,14 +28,13 @@ CompileProgramWithTransformFeedback(const std::string &vsSource,
const std::string &fsSource,
const std::vector<std::string> &transformFeedbackVaryings,
GLenum bufferMode);
ANGLE_EXPORT GLuint
CompileProgramWithGSAndTransformFeedback(const std::string &vsSource,
const std::string &gsSource,
const std::string &fsSource,
const std::vector<std::string> &transformFeedbackVaryings,
GLenum bufferMode);
ANGLE_EXPORT GLuint CompileProgram(const std::string &vsSource, const std::string &fsSource);
ANGLE_EXPORT GLuint CompileProgram(const std::string &vsSource,
const std::string &fsSource,
const std::function<void(GLuint)> &preLinkCallback);
ANGLE_EXPORT GLuint CompileProgramWithGS(const std::string &vsSource,
const std::string &gsSource,
const std::string &fsSource);
......
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