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) ...@@ -74,27 +74,12 @@ TEST_P(BindUniformLocationTest, Basic)
GLint colorBLocation = 10; GLint colorBLocation = 10;
GLint colorCLocation = 5; GLint colorCLocation = 5;
GLuint vs = CompileShader(GL_VERTEX_SHADER, essl1_shaders::vs::Simple()); mProgram = CompileProgram(essl1_shaders::vs::Simple(), fsSource, [&](GLuint program) {
GLuint fs = CompileShader(GL_FRAGMENT_SHADER, fsSource); mBindUniformLocation(program, colorALocation, "u_colorA");
mBindUniformLocation(program, colorBLocation, "u_colorB[0]");
mProgram = glCreateProgram(); mBindUniformLocation(program, colorCLocation, "u_colorC");
});
mBindUniformLocation(mProgram, colorALocation, "u_colorA"); ASSERT_NE(0u, mProgram);
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);
glUseProgram(mProgram); glUseProgram(mProgram);
...@@ -133,27 +118,12 @@ TEST_P(BindUniformLocationTest, SamplerLocation) ...@@ -133,27 +118,12 @@ TEST_P(BindUniformLocationTest, SamplerLocation)
GLint colorBLocation = 10; GLint colorBLocation = 10;
GLint samplerLocation = 1; GLint samplerLocation = 1;
GLuint vs = CompileShader(GL_VERTEX_SHADER, essl1_shaders::vs::Simple()); mProgram = CompileProgram(essl1_shaders::vs::Simple(), fsSource, [&](GLuint program) {
GLuint fs = CompileShader(GL_FRAGMENT_SHADER, fsSource); mBindUniformLocation(program, colorALocation, "u_colorA");
mBindUniformLocation(program, colorBLocation, "u_colorB[0]");
mProgram = glCreateProgram(); mBindUniformLocation(program, samplerLocation, "u_sampler");
});
mBindUniformLocation(mProgram, colorALocation, "u_colorA"); ASSERT_NE(0u, mProgram);
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);
glUseProgram(mProgram); glUseProgram(mProgram);
...@@ -275,29 +245,15 @@ TEST_P(BindUniformLocationTest, Compositor) ...@@ -275,29 +245,15 @@ TEST_P(BindUniformLocationTest, Compositor)
int multiplierLocation = counter++; int multiplierLocation = counter++;
int colorCLocation = counter++; int colorCLocation = counter++;
GLuint vs = CompileShader(GL_VERTEX_SHADER, vsSource); mProgram = CompileProgram(vsSource, fsSource, [&](GLuint program) {
GLuint fs = CompileShader(GL_FRAGMENT_SHADER, fsSource); mBindUniformLocation(program, matrixLocation, "matrix");
mBindUniformLocation(program, colorALocation, "color_a");
mProgram = glCreateProgram(); mBindUniformLocation(program, colorBLocation, "color_b");
mBindUniformLocation(program, alphaLocation, "alpha");
mBindUniformLocation(mProgram, matrixLocation, "matrix"); mBindUniformLocation(program, multiplierLocation, "multiplier");
mBindUniformLocation(mProgram, colorALocation, "color_a"); mBindUniformLocation(program, colorCLocation, "color_c");
mBindUniformLocation(mProgram, colorBLocation, "color_b"); });
mBindUniformLocation(mProgram, alphaLocation, "alpha"); ASSERT_NE(0u, mProgram);
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);
glUseProgram(mProgram); glUseProgram(mProgram);
...@@ -349,23 +305,15 @@ TEST_P(BindUniformLocationTest, UnusedUniformUpdate) ...@@ -349,23 +305,15 @@ TEST_P(BindUniformLocationTest, UnusedUniformUpdate)
const GLint nonexistingLocation = 5; const GLint nonexistingLocation = 5;
const GLint unboundLocation = 6; const GLint unboundLocation = 6;
GLuint vs = CompileShader(GL_VERTEX_SHADER, essl1_shaders::vs::Simple()); mProgram = CompileProgram(essl1_shaders::vs::Simple(), fsSource, [&](GLuint program) {
GLuint fs = CompileShader(GL_FRAGMENT_SHADER, fsSource); 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); glUseProgram(mProgram);
// No errors on bound locations, since caller does not know // No errors on bound locations, since caller does not know
...@@ -437,22 +385,11 @@ TEST_P(BindUniformLocationTest, UseSamplerWhenUnusedUniforms) ...@@ -437,22 +385,11 @@ TEST_P(BindUniformLocationTest, UseSamplerWhenUnusedUniforms)
const GLuint texLocation = 54; const GLuint texLocation = 54;
GLuint vs = CompileShader(GL_VERTEX_SHADER, essl1_shaders::vs::Simple()); mProgram = CompileProgram(essl1_shaders::vs::Simple(), fsSource, [&](GLuint program) {
GLuint fs = CompileShader(GL_FRAGMENT_SHADER, fsSource); mBindUniformLocation(program, texLocation, "tex");
});
mProgram = glCreateProgram(); ASSERT_NE(0u, mProgram);
mBindUniformLocation(mProgram, texLocation, "tex");
glAttachShader(mProgram, vs);
glDeleteShader(vs);
glAttachShader(mProgram, fs);
glDeleteShader(fs);
glLinkProgram(mProgram);
GLint linked = 0;
glGetProgramiv(mProgram, GL_LINK_STATUS, &linked);
EXPECT_NE(0, linked);
glUseProgram(mProgram); glUseProgram(mProgram);
glUniform1i(texLocation, 0); glUniform1i(texLocation, 0);
EXPECT_GL_NO_ERROR(); EXPECT_GL_NO_ERROR();
...@@ -477,23 +414,12 @@ TEST_P(BindUniformLocationTest, SameLocationForUsedAndUnusedUniform) ...@@ -477,23 +414,12 @@ TEST_P(BindUniformLocationTest, SameLocationForUsedAndUnusedUniform)
const GLuint location = 54; const GLuint location = 54;
GLuint vs = CompileShader(GL_VERTEX_SHADER, essl1_shaders::vs::Zero()); mProgram = CompileProgram(essl1_shaders::vs::Zero(), fsSource, [&](GLuint program) {
GLuint fs = CompileShader(GL_FRAGMENT_SHADER, fsSource); mBindUniformLocation(program, location, "a");
mBindUniformLocation(program, location, "b");
mProgram = glCreateProgram(); });
mBindUniformLocation(mProgram, location, "a"); ASSERT_NE(0u, mProgram);
mBindUniformLocation(mProgram, location, "b");
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); glUseProgram(mProgram);
glUniform4f(location, 0.0, 1.0, 0.0, 1.0); glUniform4f(location, 0.0, 1.0, 0.0, 1.0);
EXPECT_GL_NO_ERROR(); EXPECT_GL_NO_ERROR();
...@@ -504,20 +430,14 @@ class BindUniformLocationES31Test : public BindUniformLocationTest ...@@ -504,20 +430,14 @@ class BindUniformLocationES31Test : public BindUniformLocationTest
protected: protected:
BindUniformLocationES31Test() : BindUniformLocationTest() {} BindUniformLocationES31Test() : BindUniformLocationTest() {}
void linkProgramWithUniformLocation(GLuint vs, void linkProgramWithUniformLocation(const std::string &vs,
GLuint fs, const std::string &fs,
const char *uniformName, const char *uniformName,
GLint uniformLocation) GLint uniformLocation)
{ {
mProgram = glCreateProgram(); mProgram = CompileProgram(vs, fs, [&](GLuint program) {
mBindUniformLocation(mProgram, uniformLocation, uniformName); mBindUniformLocation(program, uniformLocation, uniformName);
});
glAttachShader(mProgram, vs);
glDeleteShader(vs);
glAttachShader(mProgram, fs);
glDeleteShader(fs);
glLinkProgram(mProgram);
} }
}; };
...@@ -538,11 +458,7 @@ TEST_P(BindUniformLocationES31Test, ConsistentWithLocationLayoutQualifier) ...@@ -538,11 +458,7 @@ TEST_P(BindUniformLocationES31Test, ConsistentWithLocationLayoutQualifier)
const GLuint texLocation = 2; const GLuint texLocation = 2;
GLuint vs = CompileShader(GL_VERTEX_SHADER, essl31_shaders::vs::Zero()); linkProgramWithUniformLocation(essl31_shaders::vs::Zero(), fsSource, "tex", texLocation);
EXPECT_NE(0u, vs);
GLuint fs = CompileShader(GL_FRAGMENT_SHADER, fsSource);
EXPECT_NE(0u, fs);
linkProgramWithUniformLocation(vs, fs, "tex", texLocation);
GLint linked = GL_FALSE; GLint linked = GL_FALSE;
glGetProgramiv(mProgram, GL_LINK_STATUS, &linked); glGetProgramiv(mProgram, GL_LINK_STATUS, &linked);
...@@ -573,11 +489,7 @@ TEST_P(BindUniformLocationES31Test, LocationLayoutQualifierOverridesAPIBinding) ...@@ -573,11 +489,7 @@ TEST_P(BindUniformLocationES31Test, LocationLayoutQualifierOverridesAPIBinding)
const GLuint shaderTexLocation = 2; const GLuint shaderTexLocation = 2;
const GLuint texLocation = 3; const GLuint texLocation = 3;
GLuint vs = CompileShader(GL_VERTEX_SHADER, essl31_shaders::vs::Zero()); linkProgramWithUniformLocation(essl31_shaders::vs::Zero(), fsSource, "tex", texLocation);
EXPECT_NE(0u, vs);
GLuint fs = CompileShader(GL_FRAGMENT_SHADER, fsSource);
EXPECT_NE(0u, fs);
linkProgramWithUniformLocation(vs, fs, "tex", texLocation);
GLint linked = GL_FALSE; GLint linked = GL_FALSE;
glGetProgramiv(mProgram, GL_LINK_STATUS, &linked); glGetProgramiv(mProgram, GL_LINK_STATUS, &linked);
...@@ -610,11 +522,7 @@ TEST_P(BindUniformLocationES31Test, LocationLayoutQualifierConflictsWithAPIBindi ...@@ -610,11 +522,7 @@ TEST_P(BindUniformLocationES31Test, LocationLayoutQualifierConflictsWithAPIBindi
const GLuint tex2Location = 2; const GLuint tex2Location = 2;
GLuint vs = CompileShader(GL_VERTEX_SHADER, essl31_shaders::vs::Zero()); linkProgramWithUniformLocation(essl31_shaders::vs::Zero(), fsSource, "tex2", tex2Location);
EXPECT_NE(0u, vs);
GLuint fs = CompileShader(GL_FRAGMENT_SHADER, fsSource);
EXPECT_NE(0u, fs);
linkProgramWithUniformLocation(vs, fs, "tex2", tex2Location);
GLint linked = GL_FALSE; GLint linked = GL_FALSE;
glGetProgramiv(mProgram, GL_LINK_STATUS, &linked); glGetProgramiv(mProgram, GL_LINK_STATUS, &linked);
...@@ -638,11 +546,8 @@ TEST_P(BindUniformLocationES31Test, ArrayOfArrays) ...@@ -638,11 +546,8 @@ TEST_P(BindUniformLocationES31Test, ArrayOfArrays)
const GLuint location = 8; const GLuint location = 8;
GLuint vs = CompileShader(GL_VERTEX_SHADER, essl31_shaders::vs::Simple()); linkProgramWithUniformLocation(essl31_shaders::vs::Simple(), fsSource, "sourceColor[1]",
EXPECT_NE(0u, vs); location);
GLuint fs = CompileShader(GL_FRAGMENT_SHADER, fsSource);
EXPECT_NE(0u, fs);
linkProgramWithUniformLocation(vs, fs, "sourceColor[1]", location);
GLint linked = GL_FALSE; GLint linked = GL_FALSE;
glGetProgramiv(mProgram, GL_LINK_STATUS, &linked); glGetProgramiv(mProgram, GL_LINK_STATUS, &linked);
......
...@@ -985,21 +985,10 @@ TEST_P(VertexAttributeTest, DisabledAttribArrays) ...@@ -985,21 +985,10 @@ TEST_P(VertexAttributeTest, DisabledAttribArrays)
for (GLint colorIndex = 0; colorIndex < maxVertexAttribs; ++colorIndex) for (GLint colorIndex = 0; colorIndex < maxVertexAttribs; ++colorIndex)
{ {
GLuint vs = CompileShader(GL_VERTEX_SHADER, vsSource); GLuint program = CompileProgram(vsSource, fsSource, [&](GLuint program) {
ASSERT_NE(0u, vs); glBindAttribLocation(program, colorIndex, "a_color");
GLuint fs = CompileShader(GL_FRAGMENT_SHADER, fsSource); });
ASSERT_NE(0u, fs); ASSERT_NE(0u, program);
GLuint program = glCreateProgram();
glBindAttribLocation(program, colorIndex, "a_color");
glAttachShader(program, vs);
glDeleteShader(vs);
glAttachShader(program, fs);
glDeleteShader(fs);
ASSERT_TRUE(LinkAttachedProgram(program));
drawQuad(program, "a_position", 0.5f); drawQuad(program, "a_position", 0.5f);
ASSERT_GL_NO_ERROR(); ASSERT_GL_NO_ERROR();
......
...@@ -116,24 +116,11 @@ GLuint CheckLinkStatusAndReturnProgram(GLuint program, bool outputErrorMessages) ...@@ -116,24 +116,11 @@ GLuint CheckLinkStatusAndReturnProgram(GLuint program, bool outputErrorMessages)
return program; return program;
} }
GLuint CompileProgramWithTransformFeedback( static GLuint CompileProgramInternal(const std::string &vsSource,
const std::string &vsSource, const std::string &gsSource,
const std::string &fsSource, const std::string &fsSource,
const std::vector<std::string> &transformFeedbackVaryings, const std::function<void(GLuint)> &preLinkCallback)
GLenum bufferMode)
{ {
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 vs = CompileShader(GL_VERTEX_SHADER, vsSource);
GLuint fs = CompileShader(GL_FRAGMENT_SHADER, fsSource); GLuint fs = CompileShader(GL_FRAGMENT_SHADER, fsSource);
...@@ -141,19 +128,22 @@ static GLuint CompileAndLinkProgram(const std::string &vsSource, ...@@ -141,19 +128,22 @@ static GLuint CompileAndLinkProgram(const std::string &vsSource,
{ {
glDeleteShader(fs); glDeleteShader(fs);
glDeleteShader(vs); glDeleteShader(vs);
glDeleteProgram(program);
return 0; return 0;
} }
GLuint program = glCreateProgram();
glAttachShader(program, vs); glAttachShader(program, vs);
glDeleteShader(vs); glDeleteShader(vs);
glAttachShader(program, fs); glAttachShader(program, fs);
glDeleteShader(fs); glDeleteShader(fs);
GLuint gs = 0;
if (!gsSource.empty()) if (!gsSource.empty())
{ {
GLuint gs = CompileShader(GL_GEOMETRY_SHADER_EXT, gsSource); gs = CompileShader(GL_GEOMETRY_SHADER_EXT, gsSource);
if (gs == 0) if (gs == 0)
{ {
glDeleteShader(vs); glDeleteShader(vs);
...@@ -166,52 +156,58 @@ static GLuint CompileAndLinkProgram(const std::string &vsSource, ...@@ -166,52 +156,58 @@ static GLuint CompileAndLinkProgram(const std::string &vsSource,
glDeleteShader(gs); glDeleteShader(gs);
} }
if (transformFeedbackVaryings.size() > 0) if (preLinkCallback)
{ {
std::vector<const char *> constCharTFVaryings; preLinkCallback(program);
for (const std::string &transformFeedbackVarying : transformFeedbackVaryings)
{
constCharTFVaryings.push_back(transformFeedbackVarying.c_str());
}
glTransformFeedbackVaryings(program, static_cast<GLsizei>(transformFeedbackVaryings.size()),
&constCharTFVaryings[0], bufferMode);
} }
glLinkProgram(program); glLinkProgram(program);
return program; return CheckLinkStatusAndReturnProgram(program, true);
} }
GLuint CompileProgramWithGSAndTransformFeedback( GLuint CompileProgramWithTransformFeedback(
const std::string &vsSource, const std::string &vsSource,
const std::string &gsSource,
const std::string &fsSource, const std::string &fsSource,
const std::vector<std::string> &transformFeedbackVaryings, const std::vector<std::string> &transformFeedbackVaryings,
GLenum bufferMode) GLenum bufferMode)
{ {
GLuint program = auto preLink = [&](GLuint program) {
CompileAndLinkProgram(vsSource, gsSource, fsSource, transformFeedbackVaryings, bufferMode); if (transformFeedbackVaryings.size() > 0)
if (program == 0) {
{ std::vector<const char *> constCharTFVaryings;
return 0;
} for (const std::string &transformFeedbackVarying : transformFeedbackVaryings)
return CheckLinkStatusAndReturnProgram(program, true); {
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) 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, GLuint CompileProgramWithGS(const std::string &vsSource,
const std::string &gsSource, const std::string &gsSource,
const std::string &fsSource) const std::string &fsSource)
{ {
std::vector<std::string> emptyVector; return CompileProgramInternal(vsSource, gsSource, fsSource, nullptr);
return CompileProgramWithGSAndTransformFeedback(vsSource, gsSource, fsSource, emptyVector,
GL_NONE);
} }
GLuint CompileProgramFromFiles(const std::string &vsPath, const std::string &fsPath) GLuint CompileProgramFromFiles(const std::string &vsPath, const std::string &fsPath)
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include <EGL/egl.h> #include <EGL/egl.h>
#include <EGL/eglext.h> #include <EGL/eglext.h>
#include <functional>
#include <string> #include <string>
#include <vector> #include <vector>
...@@ -27,14 +28,13 @@ CompileProgramWithTransformFeedback(const std::string &vsSource, ...@@ -27,14 +28,13 @@ CompileProgramWithTransformFeedback(const std::string &vsSource,
const std::string &fsSource, const std::string &fsSource,
const std::vector<std::string> &transformFeedbackVaryings, const std::vector<std::string> &transformFeedbackVaryings,
GLenum bufferMode); 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);
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, ANGLE_EXPORT GLuint CompileProgramWithGS(const std::string &vsSource,
const std::string &gsSource, const std::string &gsSource,
const std::string &fsSource); 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