Commit ed074852 by Shahbaz Youssefi Committed by Commit Bot

Add a perf test for drawing with alternating programs

The programs have a different shader interface, to force rebinding descriptor sets in the Vulkan backend. Bug: angleproject:4261 Change-Id: I7a18a441483dfe34bd40b5a30ca34b7fd0dc3219 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1990085 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent f0be7c81
...@@ -21,6 +21,7 @@ enum class StateChange ...@@ -21,6 +21,7 @@ enum class StateChange
VertexBuffer, VertexBuffer,
ManyVertexBuffers, ManyVertexBuffers,
Texture, Texture,
Program,
}; };
struct DrawArraysPerfParams : public DrawCallPerfParams struct DrawArraysPerfParams : public DrawCallPerfParams
...@@ -52,6 +53,9 @@ std::string DrawArraysPerfParams::story() const ...@@ -52,6 +53,9 @@ std::string DrawArraysPerfParams::story() const
case StateChange::Texture: case StateChange::Texture:
strstr << "_tex_change"; strstr << "_tex_change";
break; break;
case StateChange::Program:
strstr << "_prog_change";
break;
default: default:
break; break;
} }
...@@ -106,7 +110,8 @@ class DrawCallPerfBenchmark : public ANGLERenderTest, ...@@ -106,7 +110,8 @@ class DrawCallPerfBenchmark : public ANGLERenderTest,
void drawBenchmark() override; void drawBenchmark() override;
private: private:
GLuint mProgram = 0; GLuint mProgram1 = 0;
GLuint mProgram2 = 0;
GLuint mBuffer1 = 0; GLuint mBuffer1 = 0;
GLuint mBuffer2 = 0; GLuint mBuffer2 = 0;
GLuint mFBO = 0; GLuint mFBO = 0;
...@@ -124,7 +129,14 @@ void DrawCallPerfBenchmark::initializeBenchmark() ...@@ -124,7 +129,14 @@ void DrawCallPerfBenchmark::initializeBenchmark()
if (params.stateChange == StateChange::Texture) if (params.stateChange == StateChange::Texture)
{ {
mProgram = SetupSimpleTextureProgram(); mProgram1 = SetupSimpleTextureProgram();
}
if (params.stateChange == StateChange::Program)
{
mProgram1 = SetupSimpleTextureProgram();
mProgram2 = SetupDoubleTextureProgram();
ASSERT_NE(0u, mProgram2);
} }
else if (params.stateChange == StateChange::ManyVertexBuffers) else if (params.stateChange == StateChange::ManyVertexBuffers)
{ {
...@@ -151,11 +163,11 @@ void main() ...@@ -151,11 +163,11 @@ void main()
gl_FragColor = vec4(v, 0, 1); gl_FragColor = vec4(v, 0, 1);
})"; })";
mProgram = CompileProgram(kVS, kFS); mProgram1 = CompileProgram(kVS, kFS);
glBindAttribLocation(mProgram, 1, "v0"); glBindAttribLocation(mProgram1, 1, "v0");
glBindAttribLocation(mProgram, 2, "v1"); glBindAttribLocation(mProgram1, 2, "v1");
glBindAttribLocation(mProgram, 3, "v2"); glBindAttribLocation(mProgram1, 3, "v2");
glBindAttribLocation(mProgram, 4, "v3"); glBindAttribLocation(mProgram1, 4, "v3");
glEnableVertexAttribArray(1); glEnableVertexAttribArray(1);
glEnableVertexAttribArray(2); glEnableVertexAttribArray(2);
glEnableVertexAttribArray(3); glEnableVertexAttribArray(3);
...@@ -163,15 +175,21 @@ void main() ...@@ -163,15 +175,21 @@ void main()
} }
else else
{ {
mProgram = SetupSimpleDrawProgram(); mProgram1 = SetupSimpleDrawProgram();
} }
ASSERT_NE(0u, mProgram); ASSERT_NE(0u, mProgram1);
// Re-link program to ensure the attrib bindings are used. // Re-link program to ensure the attrib bindings are used.
glBindAttribLocation(mProgram, 0, "vPosition"); glBindAttribLocation(mProgram1, 0, "vPosition");
glLinkProgram(mProgram); glLinkProgram(mProgram1);
glUseProgram(mProgram); glUseProgram(mProgram1);
if (mProgram2)
{
glBindAttribLocation(mProgram2, 0, "vPosition");
glLinkProgram(mProgram2);
}
glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
...@@ -192,12 +210,34 @@ void main() ...@@ -192,12 +210,34 @@ void main()
mTexture1 = CreateSimpleTexture2D(); mTexture1 = CreateSimpleTexture2D();
mTexture2 = CreateSimpleTexture2D(); mTexture2 = CreateSimpleTexture2D();
if (params.stateChange == StateChange::Program)
{
// Bind the textures as appropriate, they are not modified during the test.
GLint program1Tex1Loc = glGetUniformLocation(mProgram1, "tex");
GLint program2Tex1Loc = glGetUniformLocation(mProgram2, "tex1");
GLint program2Tex2Loc = glGetUniformLocation(mProgram2, "tex2");
glUseProgram(mProgram1);
glUniform1i(program1Tex1Loc, 0);
glUseProgram(mProgram2);
glUniform1i(program2Tex1Loc, 0);
glUniform1i(program2Tex2Loc, 1);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, mTexture1);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, mTexture2);
}
ASSERT_GL_NO_ERROR(); ASSERT_GL_NO_ERROR();
} }
void DrawCallPerfBenchmark::destroyBenchmark() void DrawCallPerfBenchmark::destroyBenchmark()
{ {
glDeleteProgram(mProgram); glDeleteProgram(mProgram1);
glDeleteProgram(mProgram2);
glDeleteBuffers(1, &mBuffer1); glDeleteBuffers(1, &mBuffer1);
glDeleteBuffers(1, &mBuffer2); glDeleteBuffers(1, &mBuffer2);
glDeleteTextures(1, &mFBOTexture); glDeleteTextures(1, &mFBOTexture);
...@@ -282,6 +322,21 @@ void ChangeTextureThenDraw(unsigned int iterations, ...@@ -282,6 +322,21 @@ void ChangeTextureThenDraw(unsigned int iterations,
} }
} }
void ChangeProgramThenDraw(unsigned int iterations,
GLsizei numElements,
GLuint program1,
GLuint program2)
{
for (unsigned int it = 0; it < iterations; it++)
{
glUseProgram(program1);
glDrawArrays(GL_TRIANGLES, 0, numElements);
glUseProgram(program2);
glDrawArrays(GL_TRIANGLES, 0, numElements);
}
}
void DrawCallPerfBenchmark::drawBenchmark() void DrawCallPerfBenchmark::drawBenchmark()
{ {
// This workaround fixes a huge queue of graphics commands accumulating on the GL // This workaround fixes a huge queue of graphics commands accumulating on the GL
...@@ -307,6 +362,9 @@ void DrawCallPerfBenchmark::drawBenchmark() ...@@ -307,6 +362,9 @@ void DrawCallPerfBenchmark::drawBenchmark()
case StateChange::Texture: case StateChange::Texture:
ChangeTextureThenDraw(params.iterationsPerStep, numElements, mTexture1, mTexture2); ChangeTextureThenDraw(params.iterationsPerStep, numElements, mTexture1, mTexture2);
break; break;
case StateChange::Program:
ChangeProgramThenDraw(params.iterationsPerStep, numElements, mProgram1, mProgram2);
break;
case StateChange::NoChange: case StateChange::NoChange:
if (eglParams.deviceType != EGL_PLATFORM_ANGLE_DEVICE_TYPE_NULL_ANGLE || if (eglParams.deviceType != EGL_PLATFORM_ANGLE_DEVICE_TYPE_NULL_ANGLE ||
(eglParams.renderer != EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE && (eglParams.renderer != EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE &&
...@@ -350,6 +408,8 @@ ANGLE_INSTANTIATE_TEST(DrawCallPerfBenchmark, ...@@ -350,6 +408,8 @@ ANGLE_INSTANTIATE_TEST(DrawCallPerfBenchmark,
DrawArrays(NullDevice(DrawCallD3D11()), StateChange::VertexBuffer), DrawArrays(NullDevice(DrawCallD3D11()), StateChange::VertexBuffer),
DrawArrays(DrawCallD3D11(), StateChange::Texture), DrawArrays(DrawCallD3D11(), StateChange::Texture),
DrawArrays(NullDevice(DrawCallD3D11()), StateChange::Texture), DrawArrays(NullDevice(DrawCallD3D11()), StateChange::Texture),
DrawArrays(DrawCallD3D11(), StateChange::Program),
DrawArrays(NullDevice(DrawCallD3D11()), StateChange::Program),
DrawArrays(DrawCallOpenGL(), StateChange::NoChange), DrawArrays(DrawCallOpenGL(), StateChange::NoChange),
DrawArrays(NullDevice(DrawCallOpenGL()), StateChange::NoChange), DrawArrays(NullDevice(DrawCallOpenGL()), StateChange::NoChange),
DrawArrays(NullDevice(Offscreen(DrawCallOpenGL())), StateChange::NoChange), DrawArrays(NullDevice(Offscreen(DrawCallOpenGL())), StateChange::NoChange),
...@@ -361,6 +421,8 @@ ANGLE_INSTANTIATE_TEST(DrawCallPerfBenchmark, ...@@ -361,6 +421,8 @@ ANGLE_INSTANTIATE_TEST(DrawCallPerfBenchmark,
DrawArrays(NullDevice(DrawCallOpenGL()), StateChange::ManyVertexBuffers), DrawArrays(NullDevice(DrawCallOpenGL()), StateChange::ManyVertexBuffers),
DrawArrays(DrawCallOpenGL(), StateChange::Texture), DrawArrays(DrawCallOpenGL(), StateChange::Texture),
DrawArrays(NullDevice(DrawCallOpenGL()), StateChange::Texture), DrawArrays(NullDevice(DrawCallOpenGL()), StateChange::Texture),
DrawArrays(DrawCallOpenGL(), StateChange::Program),
DrawArrays(NullDevice(DrawCallOpenGL()), StateChange::Program),
DrawArrays(DrawCallValidation(), StateChange::NoChange), DrawArrays(DrawCallValidation(), StateChange::NoChange),
DrawArrays(DrawCallVulkan(), StateChange::NoChange), DrawArrays(DrawCallVulkan(), StateChange::NoChange),
DrawArrays(Offscreen(DrawCallVulkan()), StateChange::NoChange), DrawArrays(Offscreen(DrawCallVulkan()), StateChange::NoChange),
...@@ -377,6 +439,9 @@ ANGLE_INSTANTIATE_TEST(DrawCallPerfBenchmark, ...@@ -377,6 +439,9 @@ ANGLE_INSTANTIATE_TEST(DrawCallPerfBenchmark,
DrawArrays(DrawCallVulkan(), StateChange::Texture), DrawArrays(DrawCallVulkan(), StateChange::Texture),
DrawArrays(Offscreen(DrawCallVulkan()), StateChange::Texture), DrawArrays(Offscreen(DrawCallVulkan()), StateChange::Texture),
DrawArrays(NullDevice(DrawCallVulkan()), StateChange::Texture), DrawArrays(NullDevice(DrawCallVulkan()), StateChange::Texture),
DrawArrays(DrawCallVulkan(), StateChange::Program),
DrawArrays(Offscreen(DrawCallVulkan()), StateChange::Program),
DrawArrays(NullDevice(DrawCallVulkan()), StateChange::Program),
DrawArrays(DrawCallWGL(), StateChange::NoChange), DrawArrays(DrawCallWGL(), StateChange::NoChange),
DrawArrays(Offscreen(DrawCallWGL()), StateChange::NoChange), DrawArrays(Offscreen(DrawCallWGL()), StateChange::NoChange),
DrawArrays(DrawCallWGL(), StateChange::VertexAttrib), DrawArrays(DrawCallWGL(), StateChange::VertexAttrib),
...@@ -384,6 +449,8 @@ ANGLE_INSTANTIATE_TEST(DrawCallPerfBenchmark, ...@@ -384,6 +449,8 @@ ANGLE_INSTANTIATE_TEST(DrawCallPerfBenchmark,
DrawArrays(DrawCallWGL(), StateChange::VertexBuffer), DrawArrays(DrawCallWGL(), StateChange::VertexBuffer),
DrawArrays(Offscreen(DrawCallWGL()), StateChange::VertexBuffer), DrawArrays(Offscreen(DrawCallWGL()), StateChange::VertexBuffer),
DrawArrays(DrawCallWGL(), StateChange::Texture), DrawArrays(DrawCallWGL(), StateChange::Texture),
DrawArrays(Offscreen(DrawCallWGL()), StateChange::Texture)); DrawArrays(Offscreen(DrawCallWGL()), StateChange::Texture),
DrawArrays(DrawCallWGL(), StateChange::Program),
DrawArrays(Offscreen(DrawCallWGL()), StateChange::Program));
} // anonymous namespace } // anonymous namespace
...@@ -54,6 +54,15 @@ void main() ...@@ -54,6 +54,15 @@ void main()
gl_FragColor = texture2D(tex, texCoord); gl_FragColor = texture2D(tex, texCoord);
})"; })";
constexpr char kDoubleTextureFS[] = R"(precision mediump float;
varying vec2 texCoord;
uniform sampler2D tex1;
uniform sampler2D tex2;
void main()
{
gl_FragColor = texture2D(tex1, texCoord) + texture2D(tex2, texCoord);
})";
void Generate2DTriangleData(size_t numTris, std::vector<float> *floatData) void Generate2DTriangleData(size_t numTris, std::vector<float> *floatData)
{ {
for (size_t triIndex = 0; triIndex < numTris; ++triIndex) for (size_t triIndex = 0; triIndex < numTris; ++triIndex)
...@@ -118,6 +127,20 @@ GLuint SetupSimpleTextureProgram() ...@@ -118,6 +127,20 @@ GLuint SetupSimpleTextureProgram()
return program; return program;
} }
GLuint SetupDoubleTextureProgram()
{
GLuint program = CompileProgram(kSimpleTexCoordVS, kDoubleTextureFS);
if (program == 0u)
{
return program;
}
// Use the program object
glUseProgram(program);
return program;
}
GLuint Create2DTriangleBuffer(size_t numTris, GLenum usage) GLuint Create2DTriangleBuffer(size_t numTris, GLenum usage)
{ {
GLuint buffer = 0u; GLuint buffer = 0u;
......
...@@ -20,6 +20,9 @@ GLuint SetupSimpleDrawProgram(); ...@@ -20,6 +20,9 @@ GLuint SetupSimpleDrawProgram();
// Returns program ID. Uses a 2D texture. // Returns program ID. Uses a 2D texture.
GLuint SetupSimpleTextureProgram(); GLuint SetupSimpleTextureProgram();
// Returns program ID. Uses two 2D textures.
GLuint SetupDoubleTextureProgram();
// Returns program ID. The program is left in use and the uniforms are set to default values: // Returns program ID. The program is left in use and the uniforms are set to default values:
// uScale = 0.5, uOffset = -0.5 // uScale = 0.5, uOffset = -0.5
GLuint SetupSimpleScaleAndOffsetProgram(); GLuint SetupSimpleScaleAndOffsetProgram();
......
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